zoukankan      html  css  js  c++  java
  • 【effective c++】构造/析构/赋值运算

    条款5:了解c++默默编写并调用哪些函数

    如果自己没声明,编译器会声明一个copy构造函数,一个copy赋值操作符和一个析构函数。此外,如果没有声明任何构造函数,编译器会声明一个default构造函数(如果已经声明了构造函数,编译器不会创建default构造函数)。编译器生成的所有这些函数都是public且inline

    如果你打算在一个内含引用成员或const成员的class内支持赋值操作,你必须自己定义copy赋值操作符,因为c++并不允许让引用改指向不同对象,或者更改const成员,所以编译器不知道如何在自己生成的赋值操作符中处理它们。

    如果某个base class将copy赋值运算符声明为private,编译器将拒绝为其派生类生成一个copy 赋值运算符,因为编译器为派生类生成的copy赋值运算符必须可以处理base成分,但它们无法调用派生类无权调用的成员函数。

    条款6:若不想使用编译器自动生成的函数,就该明确拒绝

    声明一个成员函数,可以阻止编译器创建default版本,令函数为private,可阻止类的用户调用它。为了防止成员函数和友元函数调用前述private函数,可以只声明不定义,这样如果试图调用一个未定义的函数,会产生链接错误。

    为了将上述链接错误转移至编译期,可以设计一个专门阻止copy动作的base class,在该class中将copy相关操作声明为private且未定义,然后其他需要阻止copy动作的类继承自该base class。因为派生类中编译器生成的copy构造函数和copy赋值运算符会调用基类的copy构造函数和copy赋值运算符,编译错误。

    条款7::为多态基类声明virtual析构函数

    当派生类对象经由一个基类指针被删除,而该基类的析构函数是non-virtual,其结果未定义)(实际执行时通常发生的是对象的派生类成分没被销毁,造成资源泄漏

    条款9:绝不在构造和析构过程中调用virtual函数

    在派生类对象的基类成分构造期间(调用基类的构造函数),对象的类型是base class而不是derived class。相同道理也适用于析构函数,进入base class析构函数后对象就成为一个base class对象,而c++的任何部分包括虚函数,dynamic_cast等也都那么看待它。

    在构造和析构期间不要调用virtual函数,因为这类调用都是调用的base class中的函数,不会调用当前class中的相应函数

    条款10:令operator= 返回一个reference to *this

    为了实现链式赋值,赋值操作符必须返回一个reference指向操作符的左侧实参。这条规则适用于所有赋值相关运算,包括+=, -=, *=等

    条款11:在operator= 中处理自赋值

    class Bitmap {};
    class Widget {
    private:
        Bitmap *pb;
        Widget& operator= (const Widget &rhs);
    };
    
    // 处理了自赋值,但是如果new Bitmap导致异常,Widget会持有一个指针指向一块被删除的Bitmap
    Widget& Widget::operator= (const Widget &rhs) {
        if (this == &rhs) {
            return *this;
        }
    
        delete pb;
        pb = new Bitmap(*rhs.pb);
        return *this;
    }
    
    // 如果new Bitmap跑出异常,pb保持原状
    Widget& Widget::operator= (const Widget &rhs) {
        if (this == &rhs) {
            return *this;
        }
    
        Bitmap *pOrig = pb;
        pb = new Bitmap(*rhs.pb);
        delete pOrig;
        return *this;
    }

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

    当你编写一个copying函数(copy构造和copy赋值),请确保 1)复制所有local成员变量  2)调用所有base class内的适当的copying函数,如果不显式调用基类的copying函数,派生类对象的基类成分会被基类的default构造函数初始化

  • 相关阅读:
    iTestin云测试工具
    android 存储操作 大小显示换算 kb mb KB MB 读取
    android 发送短信 判断号码规则 判断字符数70
    android 震动 各种
    10.13总结
    10.8每日总结
    10.9
    10.15
    10.14
    10.12每日总结
  • 原文地址:https://www.cnblogs.com/ljygoodgoodstudydaydayup/p/7260118.html
Copyright © 2011-2022 走看看