虚拟继承
菱形继承:两个子类继承同一个父类,而又有子类同时继承这两个子类。
如果父类中可被子类访问的数据成员或函数成员被子类一路继承下去,那么子类中使用时会出现调用不明确。
#include <iostream>
/* 一个类有两个父类,这两个父类又都继承自同一个父类,就形成了菱形继承 */
class Base {
public:
/*virtual*/ void f() {
std::cout << "f() in Base" << std::endl;
h();
}
protected:
void g() {
std::cout << "g() in Base" << std::endl;
}
private:
void h() {
std::cout << "h() in Base" << std::endl;
}
};
class Derived1Level1 : public virtual Base {
public:
/* 这里如果加上关键字override是错误的,会提示不能重写基类成员,
原因是virtual继承和virtual function是两个概念,virtual继承并不是让每个成员都变成了虚函数
如果在virtual继承中使用虚函数那么要在函数原型中加上virtual关键字 */
void f() /*override*/{
std::cout << "f() in Derived1Level1" << std::endl;
g();
h();
}
void h() {
std::cout << "h() in Derived1Level1" << std::endl;
}
};
class Derived2Level1 : public virtual Base {
public:
void f() {
std::cout << "f() in Derived2Level1" << std::endl;
g();
// h(); // error: Base::h() is not accessible
}
};
class DerivedLevel2 : public Derived1Level1, public Derived2Level1 {
public:
void f() {
std::cout << "f() in Derived1Level2" << std::endl;
g(); // 如果Derived1Level1和Derived2Level1继承Base时不加virtual此处会提示对g的调用不明确,
// 因此虚拟继承主要是为了解决此类菱形继承的问题
Derived1Level1::h();
}
};
int main()
{
DerivedLevel2 dl2;
dl2.f();
return 0;
}
菱形继承示例
虚函数
#include <iostream>
/* 一个类有两个父类,这两个父类又都继承自同一个父类,就形成了菱形继承 */
class Base {
public:
virtual void f() {
std::cout << "f() in Base" << std::endl;
h();
}
virtual void foo() {
std::cout << "foo() in Base" << std::endl;
}
virtual void bar() {
std::cout << "bar() in Base" << std::endl;
}
protected:
void g() {
std::cout << "g() in Base" << std::endl;
}
private:
void h() {
std::cout << "h() in Base" << std::endl;
}
};
class Derived1Level1 : public virtual Base {
public:
/* 这里如果加上关键字override是错误的,会提示不能重写基类成员,
原因是virtual继承和virtual function是两个概念,virtual继承并不是让每个成员都变成了虚函数
如果在virtual继承中使用虚函数那么要在函数原型中加上virtual关键字 */
void f() /*override*/{
std::cout << "f() in Derived1Level1" << std::endl;
g();
h();
}
void h() {
std::cout << "h() in Derived1Level1" << std::endl;
}
};
class Derived2Level1 : public virtual Base {
public:
void f() {
std::cout << "f() in Derived2Level1" << std::endl;
g();
// h(); // error: Base::h() is not accessible
}
};
class DerivedLevel2 : public Derived1Level1, public Derived2Level1 {
public:
void f() {
std::cout << "f() in Derived1Level2" << std::endl;
g(); // 如果Derived1Level1和Derived2Level1继承Base时不加virtual此处会提示对g的调用不明确,
// 因此虚拟继承主要是为了解决此类菱形继承的问题
Derived1Level1::h();
}
};
int main()
{
Base b;
Derived1Level1 d1l1;
Derived2Level1 d1l2;
DerivedLevel2 dl2;
dl2.f();
return 0;
}