zoukankan      html  css  js  c++  java
  • Item 5:那些被C++默默地声明和调用的函数 Effective C++笔记

    Item 5: Know what functions C++ silently writes and calls

    在C++中,编译器会自己主动生成一些你没有显式定义的函数,它们包含:构造函数、析构函数、复制构造函数、=运算符。 有时为了符合既有设计。我们不希望自己主动生成这些函数。我们能够把它们显式声明为private。 此时在使用这些类的客户看来,它们就像不存在一样。

    class Empty{
    public:
        // 默认构造函数
        Empty(){}   
        // 拷贝构造函数
        Empty(const Empty& rhs){}   
        // 析构函数
        ~Empty(){}
        // 赋值运算符
        Empty& operator=(const Empty& rhs){}
    };
    

    这些编译器自己主动生成的缺省方法是能够禁用的,把它们声明为private便能解决绝大多数问题。 很多其它的讨论能够參考:Item 6: 禁用那些不须要的缺省方法-Effective C++笔记

    调用时机

    当我们没有显式地定义上述这四种函数时。编译器会自己主动帮我们定义。

    这些函数它们调用的时机例如以下:

    1. 构造函数:对象定义;使用其它兼容的类型初始化对象时(可使用 explicit 来避免这样的情况)
    2. 复制构造函数:用一个对象来初始化还有一对象时。传入对象參数时。返回对象时。
    3. 析构函数:作用域结束(包含函数返回)时。delete
    4. =运算符:一个对象赋值给还有一对象

    为了更清晰地说明它们的调用时机。来个样例吧:

    Empty e1;               // 默认构造函数
    Empty e2(e1);           // 拷贝构造函数
    Empty e3 = e1;          // 拷贝构造函数
    e2 = e1;                // = 运算符
    
    void func(Empty e){     // 拷贝构造函数。拷贝一份參数对象
        return e;           // 拷贝构造函数。拷贝一份返回对象
                            // 析构函数。拷贝得到的參数对象被析构
    }
    
    e2 = func(e1);          // = 运算符
                            // 析构函数。返回值被析构
    

    引用成员

    当对象包括引用成员时,拷贝和赋值行为将会变得很有趣,考虑这样一个类:

    class Person{
    public:
        string & name;
        Person(string& str): name(str){ }
    };
    string s1 = "alice", s2 = "bob";
    Person p1(s1), p2(s2);
    
    s1 = s2;
    

    赋值后,p1.name会指向p2.name吗?我们知道在C++中引用本身是不可改动的。

    即使p1.name指向了p2.name。那么对p1.name的赋值将会影响到p2? 于是。C++拒绝编译上述代码,此时我们须要手动定义一个赋值运算符。

    说来奇妙。拷贝构造函数也存在相同的问题,编译器却从不抱怨。

    能够正常编译,而且两个引用指向同一对象。

  • 相关阅读:
    POJ 基本算法(3)
    给定范围的素数筛选(POJ 2689)
    无向图、有向图的最小环
    第k短路和A*
    HDU 4302 Holedox Eating (set + iterator)
    笛卡尔树
    HDU 多校联合第一场
    HDU 多校联合第二场
    POJ 图算法(3)
    POJ 1038 Bugs Integrated, Inc. (状态dp)
  • 原文地址:https://www.cnblogs.com/cynchanpin/p/7298558.html
Copyright © 2011-2022 走看看