物件導向——類設計(一)

Inside_Zhang發表於2015-11-20
  • 如果一個類將自己的成員變數宣告為protected,則該類很有可能作為多型基類

    一個類的成員變數一般不宣告為public(如果非宣告為public不可的話,使用struct豈不是更好),而protectedprivate的區別正在於所修飾的變數是否子類可見。

  • 一個類的解構函式如果為virtual的話,則該類很多可能作為多型基類,則該類應有另外的virtual成員函式

實現一個類的順序

  • 所有封裝的成員變數
  • 圍繞成員變數的建構函式
  • 成員變數的存取
  • 其他成員變數

私有成員函式

有些類內部會有一些私有的函式,除了友元之外,
這些私有的函式只開放給類自身,也即僅會被類內部其他成員函式所呼叫,屬於勞模,屬於幹髒活累活的人,屬於幕後的工作人員,也即幕後英雄;

所以結論是什麼,私有成員函式僅被類內其他成員函式所呼叫,設計與實現的順序是,先設計私有,後設計公有。是先設計與實現私有成員函式,再實現需要依賴該私有成員函式的共有成員函式;

構成過載 vs 不構成過載?

DAttrInfo& cast_to_d();
const DAttrInfo& cast_to_d() const;

DAttrInfo& cast_to_d();
DAttrInfo& cast_to_d() const;
                                        // 以上均可構成過載
DAttrInfo& cast_to_d();
const DAttrInfo& cast_to_d();
                                        // 無法過載僅按返回型別區分的函式

預設構造和預設析構

類的預設建構函式會呼叫其全部成員變數(不包括內建型別)的預設建構函式(如果存在的話),同理類的預設解構函式會呼叫其全部成員變數的預設解構函式(如果存在的話)。

class Widget
{
public:
    Widget() { cout << "Widget::Widget()" << endl;}
    ~Widget() { cout << "Widget::~Widget()" << endl;}
};

class Test
{
private:
    int x;
    Widget w;
public:
    int get() const { return x;}
};

int main(int, char**)
{
    Test t;
    cout << t.get() << endl;
    return 0;
}

為多型基類宣告virtual解構函式

enum TimerType
{
    Atomic,
    Water,
    Writst
};
class TimeKeeper
{
public:
    /*virtual*/ ~TimeKeeper() { cout << "TimeKeeper::~TimeKeeper()" << endl;}
};

class AtomicClock :public TimeKeeper
{
public:
    ~AtomicClock() { cout << "AtomicClock::~AtomicClock()" << endl;}
};

TimeKeeper* getTimeKeeper(TimeKeeperType type)
{
    TimeKeeper* tk;
    switch(type)
    {
        case Atomic:
        tk = new AtomicClock;
        break;

        case Water:
        tk = new WaterClock;
        break;

        case Wrist:
        tk = new WristWatch;
        break;

        default:
        tk = nullptr;
        break;
    }
    return tk;
}

int main(int, char**)
{
    TimeKeeper* tk = getTimeKeeper(Atomic);
    delete tk;
            // TimerKeeper::TimerKeeper()
            // 如果解構函式不是virtual的,可見不會呼叫子類的解構函式
            // 如果將基類的解構函式宣告為virtual,
            // 當derived class物件經由base class指標刪除時,就會先呼叫基類的解構函式,再呼叫父類的解構函式
    return 0;
}

再次請深入理解,virtual函式(普通函式以及解構函式)的目的是允許derived class的實現得以客製化

相關文章