标签:地方 dia ++ mpi asp res 继承 cti 对象模型
class Point { public: Point(float x= 0.0, float y = 0.0); // ... 没有virtual function protected: float _x, _y; };没有理由须要禁止拷贝一个Point object.因此问题就变成了:默认行为是否足够?假设要支持的仅仅是一个简单的拷贝操作,那么默认行为不但足够并且有效率,没有利用再自己提供一个copy assignment operator.
不,因为坐标都内带数值,所以不会发生"别名话"或"内存泄露".假设自己提供copy assignment operator,程序反倒会运行的比較慢.
假设不正确Point供应一个copy assignment operator,而仅仅是依赖默认的memberwise copy,编译器会产生出一个实体吗?这个答案和copy constructor的情况一样:实际上不会!因为此 class 已经有了bitwise copy语意,所以implicit copy assignment operator被视为毫无用处,也根本不会被合成出来.
一个 class 对于默认的copy assignment operator,在下面情况不会表现出bitwise copy语意:
1.当 class 内带一个member object,而其 class 有一个copy assignment operator时.
2.当一个 class 的base class 有一个copy assignment operator时.
3.当一个 class 声明了不论什么 virtual functions(一定不可以拷贝右端 class object的vptr地址,由于它可能是一个derived class object).
4.当 class 继承自一个 virtual base class(不论此base class 有没有copy operator)时.
C++ Standard上说copy assignment operators并不表示bitwise copy semantics是nontrivial.实际上,仅仅有nontrivial instances才会被合成出来.
于是,对于Point class,这种赋值(assign)操作:
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)(第五章)
标签:地方 dia ++ mpi asp res 继承 cti 对象模型
原文地址:http://www.cnblogs.com/zhchoutai/p/6920361.html