關於繼承
我們在前面已經有討論過解構式加上virtual的意義
我們將在這邊來討論一下
一般的成員函式加上virtual的意義
以下三個範例在main中都使用一樣的方式呼叫
int _tmain(int argc, _TCHAR* argv[])
{
Base* pBase = new Base();
pBase->fun_1(1);
pBase->fun_1();
Inherit* pInherit = new Inherit();
pInherit->fun_1(2);
pInherit->fun_1();
Base* pNewBase = static_cast<Base*>(pInherit);
pNewBase->fun_1(3);
pNewBase->fun_1();
delete pInherit;
delete pBase;
return 0;
}
首先這個範例在編譯時是會失敗的
在 pInherit->fun_1(2); 這一行會找不到對應的函式
#include "stdafx.h"
#include <iostream>
class Base
{
public:
Base(){}
virtual ~Base(){}
void fun_1()
{
std::cout << "Base fun_1" << std::endl;
}
void fun_1(int a)
{
std::cout << "Base fun_1 a=" << a << std::endl;
}
};
class Inherit : public Base
{
public:
Inherit(){}
~Inherit(){}
void fun_1()
{
std::cout << "Inherit fun_1" << std::endl;
}
};
如果真要在繼承的物件中取與父系相同的函式名稱的話
必須要在子系的物件中加上 using Base::fun_1;
#include "stdafx.h"
#include <iostream>
class Base
{
public:
Base(){}
virtual ~Base(){}
void fun_1()
{
std::cout << "Base fun_1" << std::endl;
}
void fun_1(int a)
{
std::cout << "Base fun_1 a=" << a << std::endl;
}
};
class Inherit : public Base
{
public:
using Base::fun_1;
Inherit(){}
~Inherit(){}
void fun_1()
{
std::cout << "Inherit fun_1" << std::endl;
}
};
但是這樣會發生什麼事情呢
我們看一下輸出的結果
很明顯的
當我們要呼叫 pNewBase->fun_1(); 的時候
被執行的是父系物件中的fun_1()
這在程式執行的時候
是一件很危險的事情
接下來我們在父系的fun_1()前面加入virtual
#include "stdafx.h"
#include <iostream>
class Base
{
public:
Base(){}
virtual ~Base(){}
virtual void fun_1()
{
std::cout << "Base fun_1" << std::endl;
}
void fun_1(int a)
{
std::cout << "Base fun_1 a=" << a << std::endl;
}
};
class Inherit : public Base
{
public:
using Base::fun_1;
Inherit(){}
~Inherit(){}
virtual void fun_1()
{
std::cout << "Inherit fun_1" << std::endl;
}
};
這樣一來每個成員函式才有對應到我們應該要輸出的結果