标签:
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