//-- 不采用虚基类的方式
classA.h
#pragma once #include "grand.h" class A :public Grand { public: A(int a, int b, int c); ~A(); void testTongMingHanShu(); int m_iTingMIngBianLiang; private: }; A::A(int a, int b, int c) :Grand(a) { printf("A的构造a= %d\n", a); } A::~A() { } void A::testTongMingHanShu(){ printf("A的同名函数\n"); }
classA2.h
#pragma once #include "grand.h" class A2:public Grand { public: A2(int i); ~A2(); private: }; A2::A2(int i) :Grand(i) { printf("A2类的构造i = %d\n", i); } A2::~A2() { }
classB.h
#pragma once #include "classA.h" class B { public: B(); ~B(); void testTongMingHanShu(); int m_iTingMIngBianLiang; private: }; B::B() { } B::~B() { } void B::testTongMingHanShu(){ printf("B的同名函数\n"); }
classC.h
#pragma once #include "classA.h" #include "classB.h" #include "classA2.h" class C:public A, public A2, public B { public: C(int a, int b, int c); ~C(); private: }; C::C(int a, int b, int c) :A(a,b,c), A2(b), B() { } C::~C() { }
grand.h
#pragma once class Grand { public: Grand(int i); ~Grand(); int getValue(); private: int m_value; }; Grand::Grand(int i) :m_value(i) { printf("Grand类的构造m_value = %d \n", m_value); } Grand::~Grand() { } int Grand::getValue(){ return m_value; }
main.cpp
// ConsoleApplication17.cpp : Defines the entry point for the console application. // #include "stdafx.h" #include "classB.h" #include "classC.h" int _tmain(int argc, _TCHAR* argv[]) { C c(9,8,7); //ambiguous c的基类ab都有这个函数和变量 //c.testTongMingHanShu(); //c.m_iTingMIngBianLiang; c.A::testTongMingHanShu(); // 因为grand类中的内容被继承了两次 //c.getValue(); printf("getValue = %d \n", c.A::getValue()); //9 printf("getValue = %d \n", c.A2::getValue());//8 /* C类的基类A A2都继承了grand类, grand类的构造函数被A A2执行了两次,在A A2中分别都有一份grand的存在,在C类中包含了A A2,即C类重复继承了grand类, */ //-- 为了防止上述的 不合理,可与采用虚继承。即A A2都从grand类虚继承,一个都不能少。 return 0; }
//-- 采用虚基类的方式
与上述的不同之处在于
1.继承类 加virtual虚继承 基类
2.最终继承类 完成虚基类的初始化工作
classA.h
#pragma once #include "grand.h" //虚继承 class A : public virtual Grand { public: A(int a, int b, int c); ~A(); void testTongMingHanShu(); int m_iTingMIngBianLiang; private: }; A::A(int a, int b, int c) :Grand(a) { printf("A的构造a= %d\n", a); } A::~A() { } void A::testTongMingHanShu(){ printf("A的同名函数\n"); }
classA2.h
#pragma once #include "grand.h" //-- 虚继承 class A2 :virtual public Grand { public: A2(int i); ~A2(); private: }; A2::A2(int i) :Grand(i) { printf("A2类的构造i = %d\n", i); } A2::~A2() { }
classC.h
#pragma once #include "classA.h" #include "classB.h" #include "classA2.h" class C:public A, public A2, public B { public: C(int a, int b, int c); ~C(); private: }; //-- 最终类初始化虚基类 C::C(int a, int b, int c) :A(a, b, c), A2(b), B(), Grand(c) { } C::~C() { }
main.cpp
// ConsoleApplication17.cpp : Defines the entry point for the console application. // #include "stdafx.h" #include "classB.h" #include "classC.h" int _tmain(int argc, _TCHAR* argv[]) { C c(9,8,7); //ambiguous c的基类ab都有这个函数和变量 //c.testTongMingHanShu(); //c.m_iTingMIngBianLiang; c.A::testTongMingHanShu(); //因为grand类中的内容被A A2继承了二次(因为是虚继承,所以A A2共享虚基类grand同一份实例) //-- 采用虚继承。即A A2都从grand类虚继承,A A2虚继承一个都不能少。 printf("getValue = %d \n", c.getValue()); //7 printf("getValue = %d \n", c.A::getValue()); //7 printf("getValue = %d \n", c.A2::getValue());//7 /* 1.虚继承就是在继承时加 virtual字段 2.在最终的继承类完成虚基类的的初始化 工作(本例子是孙子类C的构造函数中 对grand类进行初始化, A A2的构造函数中初始化列表不能省 省则报错) 3.先追溯到哪个虚基类,就先构造哪个虚基类的子内容 */ return 0; }
下述 几个文件都未变过
classB.h
#pragma once #include "classA.h" class B { public: B(); ~B(); void testTongMingHanShu(); int m_iTingMIngBianLiang; private: }; B::B() { } B::~B() { } void B::testTongMingHanShu(){ printf("B的同名函数\n"); }
grand.h
#pragma once class Grand { public: Grand(int i); ~Grand(); int getValue(); private: int m_value; }; Grand::Grand(int i) :m_value(i) { printf("Grand类的构造m_value = %d \n", m_value); } Grand::~Grand() { } int Grand::getValue(){ return m_value; }