Effective C++ 条款12

复制对象时,勿忘其每一个成分

作者在本节条款提醒我们,在多重继承的情况下进行copy或者copy assignment 的operator=的编写时,一定要考虑base 类部分数据的初始化后者复制。

对比一下代码:

class Cutsomer
{
……
private:
    string name;
    string telphone;
};

class PriorityCustomer:public Cutsomer
{
public:
    PriorityCustomer()
    {
        cout<<"PriorityCustomer Ctor"<<endl;
    }
    PriorityCustomer(const PriorityCustomer& rhs)
        :priority(rhs.priority)
    {
        cout<<"PriorityCustomer Copy Ctor"<<endl;
    }
    PriorityCustomer& operator=(const PriorityCustomer& rhs)
    {
        cout<<"PriorityCustomer assign operator"<<endl;
        priority=rhs.priority;
        return *this;
    }
private:
    int priority;
};

PriorityCustomer中的数据有以下

    int priority;
    string name;
    string telphone;

而真正copy或者copy assignment的时候只处理了int priority;

我们可以看到上面的代码中忽视了base类部分的数据的处理,这时修改代码如下:

PriorityCustomer(const PriorityCustomer& rhs)
        :Cutsomer(rhs),priority(rhs.priority)
    {
        cout<<"PriorityCustomer Copy Ctor"<<endl;
    }
    PriorityCustomer& operator=(const PriorityCustomer& rhs)
    {
        cout<<"PriorityCustomer assign operator"<<endl;
        Cutsomer::operator=(rhs);
        priority=rhs.priority;
        return *this;
    }
时间: 2024-11-02 16:47:25

Effective C++ 条款12的相关文章

More Effective C++ 条款12 了解”抛出一个exception&quot;与“传递一个参数”或“调用一个虚函数”之间的差异

1. 函数return值与try块throw exception.函数接收参数与catch字句捕获异常相当类似(不仅声明形式相像,函数参数与exception传递方式都有三种:by value,by reference , ). 2. 尽管函数调用与异常抛出相当类似,“从抛出端传递一个exception到catch子句”和“从函数调用端传递一个实参到被调函数参数”仍然大有不同: 1)调用一个函数,控制权会最终回到调用端(除非函数失败以致无法返回),但是抛出一个exception,控制权不会再回到

Effective C++ -----条款12: 复制对象时勿忘其每一个成分

Copying函数应该确保复制“对象内的所有成员变量”及“所有base class成分”. 不要尝试以某个copying函数实现另一个copying函数.应该将共同机能放进第三个函数中,并由两个coping函数共同调用.如果你发现你的copy构造函数和copy assignment操作符有相近的代码,消除重复代码的做法是,建立一个新的成员函数给两者调用.这样的函数往往是private而且常被命名为init.这个策略可以安全消除copy构造函数和copy assignment操作符之间的代码重复.

effective c++ 条款12:复制对象时勿忘其每一个成分

记住:拷贝函数应该确保复制"对象内的所有成员变量"及"所有父类成分".不要尝试以某个拷贝函数实现另一个拷贝函数.应该将共同机能放进第三个函数中,并由两个拷贝函数共同调用. 下面是一个类实现了自己的拷贝函数,一起正常. void logCall(const string& funcName): class Customer { public: ... Customer(const Customer& rhs); Customer& operat

Effective C++:条款12:复制对象时勿忘其每一个成分

(一) 一个继承体系的声明: class Date {...}; class Customer { public: ... private: string name; Date lastTransaction; }; class PriorityCustomer : public Customer { public: PriorityCustomer(const PriorityCustomer& rhs); PriorityCustomer& operator=(const Priori

Effective C++ 条款11,12 在operator= 中处理&ldquo;自我赋值&rdquo; || 复制对象时不要忘记每一个成分

1.潜在的自我赋值     a[i] = a[j];     *px = *py; 当两个对象来自同一个继承体系时,他们甚至不需要声明为相同类型就可能造成别名. 现在担心的问题是:假如指向同一个对象,当其中一个对象被删,另一个也被删,这会造成不想要的结果. 该怎么办? 比如:   widget& widget:: operator+ (const widget& rhs) {    delete pd;    pd = new bitmap(*rhs.pb);    return *thi

Effective C++——条款10条,条款11和条款12(第2章)

条款10:    令operator=返回一个reference to *this Have assignment operators return a reference to *this 关于赋值,可以把它们写成连锁形式: int x, y, z; x = y = z = 15; // 赋值连锁形式 赋值采用右结合律,所以上述连锁赋值被解析为: x = (y = (z = 15)); 这里15先被赋值给z,然后其结果(更新后的z)再被赋值给y,然后其结果(更新后的y)再被赋值给x. 为了实现

effective C++ 读书笔记 条款12与条款13

条款12:确定你的public继承塑膜出is-a关系: 这个条款主要将了一些特殊情况:比如企鹅是鸟,企鹅可以继承于鸟,但是鸟会飞,企鹅却不能飞:还有让正方形继承矩形可能也会造成这种尴尬! 这个问题以前想过,但是不知道怎么解决,如果现实生活当中确实要这么使用:比如 猫 狗 鱼  猪等等许多动物继承Animal类,但是猫狗等不会游泳, 假如这里是有很多动物,不能采用鱼里面专门加一个方法!  这个现在还没想出来,条款12也没有讲如果要这么用该怎么处理就是将要避免这样. is - a; 在面向对象程序设

effective C++ 读书笔记 条款12

条款12 : 复制对象时不要忘记其每一个成分 编写一个类用来表现顾客,其中手动写出copying函数使得外界对它们的调用记录会被logged下来: #include <iostream> #include <string> using namespace std; void logCall(const string funcName) { cout<<funcName<<endl; } class Customer { public: Customer()

More Effective C++ 条款13 以reference方式捕捉exception

1. 由条款12知,如果catch子句捕获异常采用按值传递,那么被抛出的异常要被复制两次,这降低了效率,而且将派生类对象传给基类对象有可能会产生切割问题,但是按值传递也有它的好处,在catch子句重新throw异常的时候,它可以选择throw经catch子句处理过的异常还是原来的异常,这增加了灵活性(throw;) 2. 按指针传递似乎可以避免异常的复制,(虽然指针还是要被复制,不过4字节的代价不高),但是要注意指针指向的不能是局部对象,因为局部对象会被销毁,这就要求指针指向动态分配的内存,但由