2.3 程序转化语意学

一、显式的初始化操作

X x0;

void foo_bar()
{
    X x1(x0);
    X x2 = x0;
    X x3 = X(x0);
}

二、参数的初始化

把一个class object当做参数传给一个函数(或者作为一个函数的返回值),相当于以下操作:

X  xx = arg;

其中,xx代表形式参数或返回值,arg为真正的参数值(即实参)。

下面这样的调用方式:

// 已知foo函数的声明
void foo(X x0);

X xx;
// ...
foo(xx);

将转换为:

// C++伪码
// 编译器产生的临时对象
X __temp0;

// 编译器调用copy constructor
__temp0.X::X(xx);

// 重新改写函数的调用操作,以便使用上述临时对象
foo(__temp0);

三、返回值的初始化

已知如下的函数定义:

X bar()
{
    X xx;
    // ... 处理xx
    return xx;
}

bar()的返回值如何从局部对象xx中拷贝过来?Stroustrup在cfront中的解决方法是一个双阶段优化:
1、首先加入一个额外参数,类型是class object的一个reference。该参数用来存放“拷贝构建”而得的返回值。
2、在return指令之前安插一个copy constructor调用操作,以便将欲传回object的内容当做上述新增参数的初值。
3、函数的返回值为return,不返回任何值

有了这样的算法,bar()转化如下:

// C++伪码
void bar(X &__result)
{
    X xx;
    // bar()函数调用时,编译器调用X的default constructor
    xx.X::X();

    // 编译器调用copy constructor
    __result.X::X(xx);

    return;     
}

练习一下:
1、X xx = bar(); 转换为

// 不必施行default constructor ???
X xx; 
bar(xx);

2、bar().memfunc();可能被转化为:

// 编译器产生临时对象
X __temp0;
(bar(__temp0), __temp0).memfunc();

3、已知程序声明了一个函数指针:X ( *pf )(); pf = bar;,将被转化为:

void (*pf)(X &);
pf = bar;

四、Copy Constructor:要还是不要?

考虑下面的类Point3d:

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

这个类的设计者应该提供一个explicit copy constructor吗?不需要,因为该类既没有任何member(或base)class objects带有copy constructor,也没有任何的virtual base class或virtual function。所以,默认情况下,一个Point3d class object的“memberwise”初始化操作将导致“bitwise copy”(博主注:其实它们是一样的)。这样的效率很高,也很安全。因为数据成员是以数值存储的。bitwise copy既不会导致memory leak,也不会产生address aliasing,因此,既快速,又安全。

那么,该类的设计者到底应该提供一个explicit copy constructor吗?很明显不要。但如果被问及是否预见class需要大量的memberwise初始化操作,例如以传值的方式返回objects?如果回答是yes,那么提供一个copy constructor的explicit inline函数实例就非常合理——在你的编译器提供NVR的前提下。


参考文献:《深度探索C++对象模型》侯捷 译

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值