C++ 的右值引用

指针成员与拷贝构造

在 C++中,如果一个类中有一个指针成员,就要特别注意拷贝构造函数,一不小心就会出现内存泄露。一个经典的浅拷贝例子:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
#include <iostream>

using namespace std;

class HasPtrMem {
  public:

    HasPtrMem() : d(new int(0)) {
    }

    HasPtrMem(const HasPtrMem& h) : d(h.d) {
    // 直接赋值,导致a.d和b.d指向同一位置
    }

    ~HasPtrMem() {
    delete d;
    }

    int* d;


};


int main() {
    HasPtrMem a;
    HasPtrMem b(a); // 调用隐式拷贝构造函数

    cout << *a.d << endl;
    cout << *b.d << endl; // delete悬空指针,出现异常


}

稍微改下实现深拷贝

C++ 构造函数的优化

继承构造函数

在 c++中有一个规则,如果派生类使用基类的成员函数,可以通过 using 声明来完成,如下:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
#include <iostream>

using namespace std;

struct Base {
    void fun(double i) {
        cout << "Base:" << i << endl;
    }
};

struct Derived : Base {
    using Base::fun;
    void fun(int i) {
        cout << "Derived:" << i << endl;
    }
};

int main() {
    Base b;
    b.fun(4.5);  // Base:4.5

    Derived d;
    d.fun(4.5); // Base:4.5
    d.fun(1);   // Derived:1
    return 0;
}

在派生类 Derived 中使用 using 声明,派生类就拥有了两个 fun 函数的版本。派生类传入浮点字面常量 4.5,结果会调用基类的版本。在 c++11 中,这个想法被扩展到了构造函数上,子类可以通过使用 using 声明来声明继承基类的构造函数。继承构造函数只会初始化基类的成员变量,对于派生类的成员变量则无能为力。