2021年1月26日 星期二

virtual base class

使用時機
當一個class繼承自不同的多個class時,會繼承到他們的資料定義。這時可能會有重複的資料被繼承到,造成運作不符合預期,例如:

#include <iostream>
using namespace std;

class CA //common base class of CB and CC
{
public:
	int x;
	CA(int a = 0) { x = a; }
};
class CB :public CA
{
public:
	int y;
	CB(int a = 0, int b = 0) :CA(a) { y = b; }
};
class CC :public CA
{
public:
	int z;
	CC(int a = 0, int b = 0) :CA(a) { z = b; }
};
class CD : public CB, public CC
{
public:
	int w;
	CD(int a = 0, int b = 0, int c = 0, int d = 0 ,int e = 0) :CB(a, b), CC(c, d) {
		w = e;
	}
	void ShowVal() {
		cout << "x = " << CB::x << " y = " << y
		<< " x = " << CC::x << " z = " << z;
		cout << " w = " << w  << endl;
	}
};
int main()
{
	CD obj(5, 4, 3, 2, 1);
	obj.ShowVal(); //what happens?
	return 0;
}

輸出為: x = 5 y = 4 x = 3 z = 2 w = 1

如果改以virtual 方式繼承,相同的資料只會用到同一塊記憶體。例如:

#include <iostream>
using namespace std;

class CA //common base class of CB and CC
{
public:
	int x;
	CA(int a = 0) { x = a; }
};
class CB : virtual public CA
{
public:
	int y;
	CB(int a = 0, int b = 0) :CA(a) { y = b; }
};
class CC : virtual public CA
{
public:
	int z;
	CC(int a = 0, int b = 0) :CA(a) { z = b; }
};
class CD : public CB, public CC
{
public:
	int w;
	CD(int a = 0, int b = 0, int c = 0, int d = 0
		,int e = 0) : CA(a), CB(a, b), CC(c, d) {
		w = e;
	}
	void ShowVal() {
		cout << "x = " << CB::x << " y = " << y
		<< " x = " << CC::x << " z = " << z;
		cout << " w = " << w << " x = " << x << endl;
	}
};
int main()
{
	CD obj(5, 4, 3, 2, 1);
	obj.ShowVal(); //what happens?
	return 0;
}

輸出為: x = 5 y = 4 x = 5 z = 2 w = 1 x = 5


呼叫順序

constructors
first, virtual base classes in declaration order
then, other base classes in declaration order

destructors
 in the reverse order of the constructors

沒有留言:

張貼留言