class Point {
public:
Point(float x= 0.0, float y = 0.0);
// ... 没有virtual function
protected:
float _x, _y;
}; 没有理由需要禁止拷贝一个Point object.因此问题就变成了:默认行为是否足够?如果要支持的只是一个简单的拷贝操作,那么默认行为不但足够而且有效率,没有利用再自己提供一个copy assignment operator.Point a, b; a = b;由bitwise copy完成,把Point b拷贝给Point a,其间并没有copy assignment operator被调用.从语意上或从效率上考虑,这都是所需要的.注意,还是可能提供一个copy constructor,为的是把name return value(NRV)优化打开.copy constructor的出现不应该暗示出也一定要提供一个copy assignment operator.
inline Point &Point::operator=(const Point &p) {
_x = p._x;
_y = p._y;
} 现在派生出一个Point3d class(请注意是虚拟继承):class Point3d : virtual public Point {
public:
Point3d(float x = 0.0, float y = 0.0, float z = 0.0);
protected:
float _z;
};
如果没有为Point3d定义一个copy assignment operator,编译器就必须合成一个,合成而得的东西可能看起来像这样:// C++伪代码:被合成的copy assignment operator
inline Point3d &Point3d::operator=(Point3d *const this, const Point3d &p) {
// 调用base class的函数实体
this->Point::operator=(p);
// memberwise copy the derived class members
_z = p._z;
return *this;
} copy assignment operator有一个非正交性情况(nonorthogonal aspect,意指不够理想,不够严谨的情况),那就是它缺乏一个member assignment list.因此不能重写:// C++伪代码,以下性质并不支持
inline Point3d &Point3d::operator=(const Point3d &p3d) : Point(p3d), z(p3d._z)
{} 必须写成以下两种形式,才能调用base class 的copy assignment operator:Point::operator=(p3d);或
(*(Point *)this) = p3d;缺少copy assignment list,看起来或许只是一件小事,但如果没有它,编译器一般而言就没有办法压抑上一层base class 的copy operators被调用.例如,下面是个Vertex copy operator,其中Vertex也是虚拟继承自Point:
// class Vertex : virtual public Point
inline Vertex &Vertex::operator=(const Vertex &v) {
this->Point::operator(v);
_next = v._next;
return *this;
} 现在从Point3d和Vertex中派生出Vertex3d,下面是Vertex3d的copy assignment operator:inline Vertex3d &Vertex3d::operator=(const Vertex3d &v) {
this->Point::operator=(v);
this->Point3d::operator(v);
this->Vertex::operator=(v);
} 编译器如何能够在Point3d和Vertex的copy assignment operators中压抑Point的copy assignment operators呢?编译器不能够重复传统的constructor解决方案(附加上额外的参数).这是因为,和constructor以及destructor不同的是,"取copy assignment operator地址"的操作是合法的.因此,下面这个例子是合法程序代码(虽然它也推翻了希望把copy assignment operator做的更精巧的企图):typedef Point3d &(Point3d::*pmfPoint3d) (const Point3d &); pmfPoint3d pmf = &Point3d::operator=; (x.*pmf)(x);//看不懂.................................
inline Vertex3d &Vertex3d::operator=(const Vertex3d &v) {
init_bases(v);
} 事实上,copy assignment operator在虚拟继承情况下行为不佳,需要特别小心地设计和说明.inline Vertex3d &Vertex3d::operator=(const Vertex3d &v) {
this->Point3d::operator=(v);
this->Vertex:;operator=(v);
// must place this last if your compiler dose not suppress intermediate class invocations
this->Point::operator=(v);
} 这并不能省略subobjects的多重拷贝,但却可以保证语意正确.另一个解决方案要求把 virtual subobjects拷贝到一个分离的函数中,并根据call path条件化调用它.版权声明:本文为博主原创文章,未经博主允许不得转载。
C++对象模型——对象复制语意学 (Object Copy Semantics)(第五章)
原文:http://blog.csdn.net/yiranant/article/details/47667865