栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > C/C++/C#

【C++对象模型】 | 【04】程序转化语义

C/C++/C# 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

【C++对象模型】 | 【04】程序转化语义

文章目录
  • 一、程序转化语义
    • 1、显示的初始化操作
    • 2、参数的初始化
    • 3、返回值的初始化
    • 4、在使用层面做优化
    • 5、在编译器层面做优化
    • 6、是否需要拷贝构造?
    • 7、成员初始化

一、程序转化语义
我们所写的代码,在内部是如何转换进行优化;
1、显示的初始化操作
class X{};
X x0;

void foo_bar() {
	X x1(x0);
	X x2 = x0;
	X x3 = X(X0);
}
会经过两个必要从程序转化阶段:
- 重写每一个定义(占用内存的行为),其中的初始化操作会被剥除;
- class的拷贝构造会被安插;

2、参数的初始化
方法一:当一个类对象作为参数,会导入临时性的对象,并调用拷贝构造将其初始化,在将临时的对象交给函数,当离开函数时,将会调用其析构函数释放;

方法二:以拷贝建构方式,把实际参数建构在位置上,记录在堆栈中,在函数返回之前将其析构;
X xx;       // X __temp0
            // __temp0.X::X(xx);
foo(xx);    // foo(__temp0);
3、返回值的初始化
返回值从局部对象中拷贝返回一般做一个双阶段转换:
- 先加上一个额外参数(reference),用来放置拷贝建构的返回值;
- 在return前插入拷贝构造调用的操作,将要返回的内容拷贝到reference中;
X bar() {   // void bar(X& __result)   添加额外参数
    X xx;   // X xx;
            // xx.X::X();  默认构造
            // __result.X::XX(xx);  拷贝构造
    return xx; // return;  无返回值
}

void test(){
    X xx = bar();   // X xx;
                    // bar(xx);
}

void test2() {
    bar().memfunc();    // X __temp0;
                        // (bar(__temp0), __temp0).memfunc();
}
4、在使用层面做优化

21. 必须返回对象时,别返回reference

在这个条例上告诉我们如何将一个对象进行返回,效率会比较高;
X bar(const T& y, const T& z) { // void bar(X &__result)
	return X(y, z);				// __result.X::X(y, z);	// 通过计算,而不是拷贝构造而得来的
								// return;
} 
5、在编译器层面做优化
编译器将result参数取代named return value(NRV);
该优化能大大的提供程序效率,但由于时编译器完成,故不能明确知道是否有被优化,且当函数较为复杂时,也难以被优化;
X bar() {		// void bar(X& __result)
	X xx;		// 默认构造被调用 __result.X::X()
				// 拷贝__result....
	return xx;
}
6、是否需要拷贝构造?
class Point3d {
public:
	Point3d(float x, float y, float z);
private:
	float _x, _y, _z;
};
根据以上的情况下,由于没有【1.类成员2.基类3.虚基类4.虚函数】带有拷贝构造;故在此情况下对成员进行bitwise copy即可;
如果类需要大量的memberwise操作,那么我们需要提供一个explicit inline的拷贝构造;
Point3d::Point3d(const Point3d& rhs) {
	// 扩张 __vptr__Point3d = __vtbl__Point3d;	若有虚函数
	memcpy(this, &rhs, sizeof(Point3d));
}
但使用memcpy()还是memset(),只有在类内不含任何由编译器产生的内部成员时才会有效运行;否则将会导致成员初值被改写;
7、成员初始化

4. 确定对象被使用前已先被初始化

class Word {
private:
	string name;
	 int val;
public:
	Word() : name(0) {
		// name.string::string(0);
	}	
};
转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/853960.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号