virtual學習

// virtual學習.cpp : 定義控制檯應用程序的入口點。
//

#include "stdafx.h"
#include <iostream>

class father
{
public:
    father(){};
    // 析構爲純虛函數,防止派生類析構不完整
    virtual ~father() = default;
    // 基類自定義構造函數
    father(int Num)
        :m_nNum(Num)
    {
        
    }
public:
    void notVirtualFunc()
    {
        std::cout << "father not Virtual Func!" << std::endl;
    }
    virtual void VirtualFunc()
    {
        std::cout << "father Virtual Func!" << std::endl;
    }
    virtual void SonVirtualFunc() = 0;
private:
    int m_nNum;
};

class son 
    :public father
{
public:
    son(){};
    ~son(){};
    son(int Num1, int Num2) :
        father(Num1), m_nSonNum(Num2)
    {

    }
public:
    void notVirtualFunc()
    {
        std::cout << "son not Virtual Func!" << std::endl;
    }
    void  VirtualFunc()
    {
        std::cout << "son Virtual Func!" << std::endl;
    }
    void SonVirtualFunc()
    {
        std::cout << "son SonVirtual Func!" << std::endl;
    }
    int m_nSonNum;
};

class grandson final // 加final表示不可以被繼承
    :public son
{
public:
    grandson(){};
    ~grandson(){};
    // 派生類構造函數只初始化它的直接基類,即不能用father的構造函數初始化grandson
    grandson(int Num1, int Num2, int Num3)
        :son(Num1, Num2), m_nGrandsonNum(Num3)
    {

    }
public:
    void notVirtualFunc()
    {
        std::cout << "grandson not Virtual Func!" << std::endl;
    }
    void  VirtualFunc() override    // 保證派生類重寫基類函數
    {
        std::cout << "grandson Virtual Func!" << std::endl;
    }
    void SonVirtualFunc()
    {
        std::cout << "grandson SonVirtual Func!" << std::endl;
    }
    int m_nGrandsonNum;
};

void Print(father&f)
{
    f.notVirtualFunc();
    f.VirtualFunc();
    f.SonVirtualFunc();
    // 強調基類,迴避虛函數的機制,只調用基類函數,不管子類動態綁定
    f.father::VirtualFunc();
    std::cout << std::endl;
}

int _tmain(int argc, _TCHAR* argv[])
{
    // 含有純虛函數時,相當於一個函數接口,不能創建實例
    //father f;
    son s(9, 8);
    grandson g(1, 2, 3);

    //Print(f);
    // 發生動態綁定時,如果基類成員函數定義爲virtual,則會調派生類的函數,對基類進行覆蓋;否則直接繼承父類函數,不進行改變
    // 不管多少層繼承,只要father基類定義的爲非virtual,則所有子孫調用的都是基類的函數
    // father 定義爲virtual,son相同的函數定義爲virtual或非virtual,grandson發生動態綁定時,所調用的函數爲grandson自己的函數
    Print(s);
    Print(g);
    system("pause");
	return 0;
}

根據C++Primer學習,後續可能補充

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