1. 程式人生 > >c++虛擬函式和虛繼承

c++虛擬函式和虛繼承

1.多繼承可能會出現奇葩現象,多個同樣的變數,導致子類不知道呼叫的那個變數來自哪個父類。

2.如果一個外部方法的引數是父類,那麼即使傳了一個子類,在方法中呼叫這個類的內部方法,不管你傳入的是子類還是父類,都會強行給你呼叫父類的方法。因為編譯器認為這樣是安全的,這個方法一定在父類中可以找得到,哪怕你子類也定義了自己的方法。

關鍵字virtual用於父類方法,如果傳了一個子類物件,並且子類重寫了父類的這個virtual方法,就會呼叫子類的方法。傳誰就呼叫誰,這個就是多型。我記得java是先在子類那裡找,沒有才回去父類。

使用虛擬函式:


沒有使用:


不具備多型性

#include<iostream>
using namespace std;

class A
{
public:
A()
{
//用x表示遇到A的預設建構函式
this->name = 'x';
}
A(char name)
{
this->name = name;
}
virtual void run()
{
cout<<"A run ,actual object is:"<<this->name<<endl;
}
char name;
};
//run方法用來測試多型
class B:virtual public A
{
public:
B(char name):A(name)
{
this->name = name;
}
void run()
{
cout<<"B run ,actual object is:"<<this->name<<endl;
}
};
//虛繼承A
class C:virtual public A
{
public:
C(char name):A(name)
{
this->name = name;
}
void run()
{
cout<<"C run ,actual object is:"<<this->name<<endl;
}
};
//多繼承與虛繼承
//誰繼承在後,那麼會出現歧義的那個變數就歸誰管。
class D:public B,public C
{
public:
D(char bname,char cname):B(bname),C(cname)
{
}
//一定要重寫這個方法,不然run方法又要模稜兩可了
//反正不寫會報錯
void run()
{
cout<<"D run ,actual object is:"<<this->name<<endl;
}
};

void start(A& a)
{
a.run();
}

int main()
{
A a('a');
B b('b');
D d('b','c'); 

start(a);
start(b);

//如果d的父類不採用虛繼承的方式繼承父類,那麼這裡會出現指代不明
cout<<b.name<<endl;
//如果不虛繼承,就會報錯
cout<<d.name<<endl;
//沒有父類虛繼承爺爺,子類就要向下面這麼寫
//cout<<d.B::name<<'\t'<<d.C::name<<endl;

return 0;

}