顯示具有 cpp 標籤的文章。 顯示所有文章
顯示具有 cpp 標籤的文章。 顯示所有文章

2021年4月18日 星期日

[Effective C++] [閱讀心得]: public 繼承代表 is-a 的關係

Photo by Hamza NOUASRIA on Unsplash

所謂 is-a 代表能施加在父類別的每一件事情也要能夠施加在子類別身上,Scott Meyers 在書中舉了一個鮮明的例子

class Bird {
public:
    virtaul void fly();
    ...
};

class Penguin : public Bird {
    ...
};

在這個例子中, Penguin 是一種 Bird,但是 Penguin 並不會飛,這就違反了 is-a 的關係。因此,這樣的塑模方式並不正確。比較理想的方式是

2021年3月20日 星期六

[Effective C++] [閱讀心得]: 為何要使用前置宣告(Forward Declaration)

// A.h

class A { ... };

// B.h
#include "A.h"

class B {
...
private:
    A a;
...
};

上面這段程式碼中,由於 B 類別擁有 A 類別的成員變數,因此必須引入定義 A 類別的 A.h。然而,這樣做的缺點是,每當 A.h 內發生任何變動時,引入 B.h 的編譯單元也必須重新編譯。如果大型專案中存在著很多這樣的依賴關係的話,那麼專案的編譯時間就會變得很長。

2021年2月27日 星期六

[Effective C++] [閱讀心得]: 關於建構函式與解構函式

 為Base class宣告virtual的解構函式


class Base {
public:
    Base();
    ~Base();
    ...
};

class Derived : public Base { ... };

Base *getBase() { ... }

void foo() {
    Base *base = getBase();
    ...
    delete base;
}

這段程式碼中,getBase()回傳一個指標,此指標可能指向一個Base物件或是Derived物件。假設今天base指向了一個Derived的物件,那麼後面的delete base可能會導致物件無法完全銷毀的問題。

2021年2月20日 星期六

[Effective c++] [閱讀心得]: 條款13: 以對象管理資源

Photo by Alvaro Reyes on Unsplash

class A { ... };

void foo() {
    A a = new A;
    ...
    if (...) {
        delete a;
        return;
    }
    ...
    delete a;
    return;
}

如同上面的例子,因為if condition成立時foo()會提前return,所以必須在其中delete a,以免產生記憶體洩漏。
然而,這樣的撰寫風格其實具有極高的風險性。