2.3程序转化语意学

显示的初始化操作

已知有如下代码:

X x0
void foo_bar() {
	X x1(x0);  // 定义另了x1,x2,x3
	X x2 = x0;
	X x3 = X(x0);
}

上述必要的程序转化有两个阶段:

  1. 重写每一个定义,其中的初始化操作会被剔除
  2. classcopy constructor调用操作会被安插进去

在明确双阶段转化后,foo_bar()可能看起来像这样:

// 伪代码
void foo_bar() {
	X x1;  定义重写,其中的初始化操作会被剔除
	X x2;
	X x3;
	
	// 编译器安插X copy construction调用操作
	x1.X::X(x0);
	x2.X::X(x0);
	x3.X::X(x0);
}

其中的:x1.X::X(x0)就表现出对以下的copy constructor的调用:X::X(const X& xx)

返回值的初始化
X bar() {
	X xx;
	return xx;
}

你可能会问bar()的返回值如何从局部对象xx中拷贝过来?

  1. 首先加上一个额外的参数,类型是class object的一个reference.
  2. 在return指令之前安插一个copy constructor调用操作,以便將欲传回之object的内容当作上述新增参数的初始值
// 伪代码
void bar(X& __result) { //加上一个额外参数
	X xx;
	// 编译器所产生的default constructor操作
	xx.X::X();
	// 编译器所产生的copy constructor操作
	__resutl.X::XX(xx);
	return;
}
在编译器层面做优化
class test
{
public:
    friend test foo(double);
    test() {
        memset(array, 0, 100 * sizeof(double));
    }

    double array[100];
};
inline test::test(const test& t) {
    memcpy(this, &t, sizeof(test));
}
test foo(double val) {
    test local;
    local.array[0] = val;
    local.array[1] = val;
    local.array[2] = val;
    return local;
}

int main(int argc, char *argv[])
{
    for (int cnt = 0; cnt < 10000000; cnt++){
        test t = foo(double(cnt));
    }
}

这个程序的第一个版本不能实施NRV优化,因为test class缺少一个copy constructor。第二个版本加上`inline copy constructor:

inline test::test(const test& t) {
    memcpy(this, &t, sizeof(test));
}

第三个批评则是从相反的方向出:

void foo() {
	// 这里希望有个copy constructor
	X xx = bar();
	// 这里调用destructor
}

在此情况下,对称性被优化打破了;程序虽然比较快,却是错误的;

这样的需求在许多陈股息可能被征以严格的"效率税",例如:

X xx0(1024);
X xx1 = X(1024);
X xx2 = (X) 1024;

在第二行和第三行中,语法明显的提供了两个步骤初始化操作:

  1. 將一个临时性的object设以初值1024
  2. 將临时性的object以拷贝构造的方式作为explicit object的初始值
Copy Constructor:要还是不要?

已知如下坐标类:

class Point3d {
public:
	Point3d{float x, float y, float z};
private:
	float _x,_y,_z;
};

上述三个坐标成员是以数值来存储的,bitwise copy既不会导致memory leak也不会产生address aliasing

那么这个class的设计者是否应该提供一个explicit copy constructor?答案是否;因为编译器为你实施了最好的行为;
如果你被问及是否预见class需要大量的memberwise初始化操作,例如传值的的方式传回objects?如果答案是yes,那么提供一个copy constructorexplicit inline函数实例久非常合理;

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值