📜  C++中的虚拟基类

📅  最后修改于: 2021-05-30 08:42:18             🧑  作者: Mango

虚拟基类用于虚拟继承中,以防止在使用多个继承时给定类的多个“实例”出现在继承层次结构中。

需要虚拟基类:
考虑一下我们有一个类A的情况。这个类A是由另外两个类BC继承的。这两个类都在新的类D中继承到另一个类,如下图所示。

从图中可以看出,类A的数据成员/函数被继承了两次给类D。一类通过B类,第二类通过C类。当类D的对象访问类A的任何数据/函数成员时,就会产生关于哪个数据/函数成员将被调用的歧义?一个是通过B继承的,另一个是通过C继承的。这会使编译器感到困惑,并显示错误。

示例:显示在C++中对虚拟基类的需求

#include 
using namespace std;
  
class A {
public:
    void show()
    {
        cout << "Hello form A \n";
    }
};
  
class B : public A {
};
  
class C : public A {
};
  
class D : public B, public C {
};
  
int main()
{
    D object;
    object.show();
}

编译错误:

prog.cpp: In function 'int main()':
prog.cpp:29:9: error: request for member 'show' is ambiguous
  object.show();
         ^
prog.cpp:8:8: note: candidates are: void A::show()
   void show()
        ^
prog.cpp:8:8: note:                 void A::show()

如何解决这个问题?
为了解决类A在类B和类C中都被继承时的歧义,通过将关键字virtual声明为virtual as来将其声明为virtual基类

虚拟基类的语法:

Syntax 1:
class B : virtual public A 
{
};

Syntax 2:
class C : public virtual A
{
};

注意: virtual可以在公共之前或之后编写。现在,仅一个数据/函数成员的副本将被复制到类C和类B,而类A成为虚拟基类。
虚拟基类提供了一种节省空间并避免使用多个继承的类层次结构产生歧义的方法。当基类被指定为虚拟基类时,它可以多次用作间接基类,而无需重复其数据成员。使用虚拟基的所有基类都共享其数据成员的单个副本。

例子1

#include 
using namespace std;
  
class A {
public:
    int a;
    A() // constructor
    {
        a = 10;
    }
};
  
class B : public virtual A {
};
  
class C : public virtual A {
};
  
class D : public B, public C {
};
  
int main()
{
    D object; // object creation of class d
    cout << "a = " << object.a << endl;
  
    return 0;
}
输出:
a = 10

说明:A只有一个公共的数据成员a 。该类实际上是在B类和C类中继承的。现在,类B和类C变为虚拟基类,并且没有重复执行数据成员a的操作。

范例2:

#include 
using namespace std;
  
class A {
public:
    void show()
    {
        cout << "Hello from A \n";
    }
};
  
class B : public virtual A {
};
  
class C : public virtual A {
};
  
class D : public B, public C {
};
  
int main()
{
    D object;
    object.show();
}
输出:
Hello from A
要从最佳影片策划和实践问题去学习,检查了C++基础课程为基础,以先进的C++和C++ STL课程基础加上STL。要完成从学习语言到DS Algo等的更多准备工作,请参阅“完整面试准备课程”