在operator=或拷贝构造中对所有数据成员赋值
来源:互联网 发布:linux c 过去系统时间 编辑:程序博客网 时间:2024/05/23 13:15
1. operator=赋值操作符
Effective C++条款16中描述到,在派生类中重写赋值操作符函数时,要注意不要忘记对基类对象部分也要赋值,而这一点恐怕是许多新手容易忘记的,他们很自然地不会想到这一点(例如我),比如下述代码:
class CBase{public: CBase& operator=(const CBase& another) { if (this!=&another) { base=another.base; } return *this; } CBase(int a):base(a){} int Value(){return base;}protected: int base;};class CDerived : public CBase{public: CDerived& operator=(const CDerived& another) { if (this == &another) { return *this; } // call baseclass's operator= //CBase::operator=(another); derived=another.derived; return *this; } CDerived(int b):derived(b),CBase(b){} int Value(){return derived;} int BaseValue(){return base;}private: int derived;};int main(){ CDerived d1(3); cout<<"Derived Object 1: Base:"<<d1.BaseValue()<<"\t"<<"Derived:"<<d1.Value()<<"\n"; CDerived d2(4); cout<<"Derived Object 1: Base:"<<d2.BaseValue()<<"\t"<<"Derived:"<<d2.Value()<<"\n"; d1=d2; cout<<"After Assignment: Base:"<<d1.BaseValue()<<"\t"<<"Derived:"<<d1.Value()<<"\n"; return 0;}
上述例子中,派生类CDerived的赋值操作符函数没有将基类CBase对象部分的成员赋值,则基类对象的成员base仍然维持原值, 输出为:
Derived Object 1: Base:3 Derived:3Derived Object 2: Base:4 Derived:4After Assignment: Base:3 Derived:4如果将CBase::operator=(another);这一行的注释去掉,则可以成功将基类对象部分的成员进行赋值:
Derived Object 1: Base:3 Derived:3Derived Object 2: Base:4 Derived:4After Assignment: Base:4 Derived:4
2. 拷贝构造函数
同样地,拷贝构造函数中也要注意调用基类版本的拷贝构造函数,这样才可以达到完全复制的目的:
class CBase{public: CBase& operator=(const CBase& another) { if (this!=&another) { base=another.base; } return *this; } CBase(const CBase& another):base(another.base){} CBase(int a=0):base(a){} int Value(){return base;}protected: int base;};class CDerived : public CBase{public: //Version1:CDerived(const CDerived& another):derived(another.derived){} //Version2:CDerived(const CDerived& another):derived(another.derived),CBase(another){} CDerived& operator=(const CDerived& another) { if (this == &another) { return *this; } // call baseclass's operator= //CBase::operator=(another); derived=another.derived; return *this; } CDerived(int b=1):derived(b),CBase(b){} int Value(){return derived;} int BaseValue(){return base;}private: int derived;};int main(){ CDerived d1(3); cout<<"Derived Object 1: Base:"<<d1.BaseValue()<<"\t"<<"Derived:"<<d1.Value()<<"\n"; CDerived d2(d1); cout<<"After Copy Construction: Base:"<<d2.BaseValue()<<"\t"<<"Derived:"<<d2.Value()<<"\n"; return 0;}
如果派生类拷贝构造函数采用上例中Version1版本,则输出为:
Derived Object 1: Base:3 Derived:3After Copy Construction: Base:0 Derived:3
基类部分的变量base没有被拷贝,实际上,基类部分的初始化是通过调用基类默认构造函数完成的,因此base的值为0
如果派生类拷贝构造函数采用上例中Version2版本,则输出为:
Derived Object 1: Base:3 Derived:3After Copy Construction: Base:3 Derived:3
这样就达到了拷贝对象的目的。
总结
对于生成对象的三个函数:构造函数,拷贝构造函数和operator=函数,我们不仅仅要关注派生类成员变量的赋值或初始化,也要关注基类成员变量,不能遗漏。
- 在operator=或拷贝构造中对所有数据成员赋值
- 在operator=中对所有数据成员赋值
- 在operator=中对所有数据成员赋值
- Effective C++学习笔记:在operator=中对所有数据成员赋值
- 条款16: 在operator=中对所有数据成员赋值
- Effective C++ 条款16: 在operator=中对所有数据成员赋值
- effective C++笔记之条款16: 在operator=中对所有数据成员赋值
- 条款16:在operator =中对所有数据成员赋值
- 条款 16: 在 operator=中对所有数据成员赋值
- 拷贝构造函数和赋值操作符operator=分别在什么时候被调用?
- C++拷贝构造函数和赋值操作(operator=)
- day_06_拷贝构造、拷贝赋值、静态成员
- C++中使用初始化列表比在构造函数中对成员变量赋值更高效
- 对拷贝构造函数与operator=的理解
- 在operator=中处理自我赋值
- 【转帖】拷贝构造函数与赋值构造函数(operator=)的区别
- 拷贝构造函数与赋值构造函数(operator=)之区别
- 拷贝构造函数与赋值构造函数(operator=)的区别
- window环境solr在tomcat中的安装 Solr with Apache Tomcat
- Android 面试总结
- 44、Oracle数据库设计(定义约束 外键约束)
- 可以删除的安卓Android系统自带程序列表
- 嵌入式开发基础3
- 在operator=或拷贝构造中对所有数据成员赋值
- 关于MSDN for VB6和VC6
- linux 下的vsftp
- linux文本处理工具之sed
- android自带主题
- 45、ORACLE to_char函数详解
- Jquery 示例二 简单动画
- 使用 EclEmma 进行覆盖测试
- 基于Java Socket客户端、服务端聊天雏形