關於這個虛繼承,真是挨千刀的家伙,每次遇到筆試題,真是必考呀,你說都不能換個花樣嗎?真心的容易出錯,今天特意來做個總結,讓這個挨千刀的家伙,去死去吧!虛函數概念就不多介紹了,主要的作用就是實現多態。先看一段代碼:
一、父類不是虛的,你個兒子再虛也不行,還是沒你老子堅挺!
[cpp]
#include <iostream>
using namespace std;
class A
{
public :
void find()
{
cout<<"find::A"<<endl;
}
virtual void get()
{
cout<<"get::A"<<endl;
}
};
class B:public A
{
public :
void find()
{
cout<<"find::B"<<endl;
}
virtual void get()
{
cout<<"get::B"<<endl;
}
};
int main()
{
A *a=new B();
a->find();
a->get();
return 0;
}
大家看上面代碼,會輸出什麼呢?
答案是:
find::A
get::B
假如我們把上面的代碼:A中的get()方法去掉virtual關鍵字,改為一般的函數。結果又是如何的呢?
答案:
find::A
get::A
這個裡面就是發生了虛函數的覆蓋問題。
二、小試牛刀
繼續看下面代碼:
[cpp]
class A
{
public :
virtual void get()
{
cout<<"A"<<endl;
}
};
class B:public A
{
public :
virtual void get()
{
cout<<"B"<<endl;
}
};
int main()
{
A *pa=new A();
pa->get();
B *pb=(B*)pa;
pb->get();
delete pa,pb;
pa=new B();
pa->get();
pb=(B*)pa;
pb->get();
return 0;
}
輸出: A A B B
以上兩個例子都是關於虛函數覆蓋虛函數的問題。 B *pb=(B*)pa; 這個我們看到強制轉換,但是pa這個指針並沒有發生改變,所指向的內容也沒有發生改變,所以我們知道pb指向的依然是pa所指向的內容。
delete pa,pb。刪除了pa,pb所指向的地址,但是pa,pb並沒有被刪除,屬於懸掛指針。我們重新給pa賦值,指向B,故pa->get();輸出了B
三、虛繼承你知道是啥不!
[cpp]
// MicroTest.cpp : Defines the entry point for the console application.
//
#include "stdafx.h"
#include <iostream>
using namespace std;
class A
{
public:
void getA()
{
cout<<"A";
}
virtual void getAA()
{
cout<<"1";
}
};
class B:public A
{
public:
virtual void getA()
{
cout<<"B";
}
virtual void getAA()
{
cout<<"2";
}
};
class C:virtual public A
{
public:
void getA()
{
cout<<"C";
}
virtual void getAA()
{
cout<<"3";
}
};
int main(int argc, char* argv[])
{
printf("Hello World!\n");
A *a=new B();
A *b=new C();
a->getA();
a->getAA();
b->getA();
b->getAA();
return 0;
}