C++基础 多重继承引发的 虚基类与虚继承(基类被虚继承 就称为虚基类?)
作者:互联网
//-- 不采用虚基类的方式
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;
}
标签:grand,继承,基类,C++,int,A2,Grand,include,public 来源: https://blog.csdn.net/baidu_19552787/article/details/120485587