Effective C++ 改善程序設計的55個具體做法 學習筆記(二)

接上一篇文章

https://mp.csdn.net/console/editor/html/106482664

條款05:瞭解C++默默編寫並調用了哪些函數

class A
{

};

我們在程序中創建這麼一個類,看似是空的類,其實這裏面存在C++默認寫好並且隱藏的成員函數。

class A
{
public:

A(){}                          //無參數構造函數

A(const A&){}                  //拷貝構造函數

~A(){}                         //析構函數

A& operator=(const A&){}       //重載=運算符
}

這麼寫一般不會出問題。但是在以下幾種情況會出問題:

(1)成員變量中含有引用參數。

如下:

class MyClass
{
public:
    MyClass(int tmp_value);

    int &m_Value;
};

MyClass::MyClass(int tmp_value)
    :m_Value(tmp_value)
{

}

void main()
{
    MyClass temp_MyClass(10);
    MyClass temp_MyClassB(20);
    temp_MyClass = temp_MyClassB;              //這個操作編譯器不允許。寫上報錯。
}

條款06:若不想使用編譯器自動生成的函數,就該明確拒絕。

OK拒絕最常用方法有兩個:

(1)將默認函數寫出來,寫在private裏,禁止別人訪問。

(2)寫個基類,該類就把C++默認寫好的這三個函數寫成private的。其他要實現的類去private繼承他。(不過這樣整容易整亂)

條款07:爲多態基類生命virtual析構函數

直接看代碼

//父類頭文件
class MyClass
{
public:
    MyClass();
    ~MyClass();

};


//源文件
#include "myclass.h"
#include<QDebug>
MyClass::MyClass()
{

}

MyClass::~MyClass()
{
    qDebug("delete MyClass");
}

//子類
#include"myclass.h"

class MySon : public MyClass
{
public:
    MySon();
    ~MySon();
};

//源文件
#include "myson.h"
#include<QDebug>
MySon::MySon()
{

}

MySon::~MySon()
{
    qDebug("delete my son");
}

我們用父對象的指針創建子對象。(工廠模式常用),然後delete掉

    MyClass *temp_MyClass = new MySon;
    delete temp_MyClass;

後臺打印語句爲

可以看到,我們析構的時候並沒有走子類的析構函數。如果在子類構造函數中申請空間,在子類的析構函數中釋放,這樣做就會產生內存泄漏。

解決方法是

父類的析構函數前面加上virtual

    virtual ~MyClass();

後臺打印語句爲

注意:如果一個類不會去作爲基類這種使用,那麼不要用virtual來修飾析構函數。

PS書中說的任何一個帶有virtaul函數的類都應該有一個虛析構,這句話的意思可能是如果一個類要作爲基類使用,那麼最好把這個類的析構函數改寫成虛析構函數。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章