如何正确获得虚拟继承?

El *_*ude 0 c++ abstract-class virtual-inheritance c++11

在下面的示例中,我有我的父类和两个子类。任何一个孩子的对象都存储在父母的向量中。循环遍历向量我只能看到来自父类的方法调用。

如何正确获得方法定义和 vtables 以及如何避免切片效应。我一直在做 Python 太长时间了,这样的事情会起作用。

#include <iostream>
#include <vector>


using namespace std;

class A{
    public:

        virtual string print(){return string("A");};
};

class B: public A{
    virtual string print() final {return string("B");};
};

class C: public A{
    virtual string print() final {return string("C");};
};

int main()
{

   vector<A> v;
   v.push_back(B());
   v.push_back(C());

   for(auto x : v){
       cout << x.print() << endl;
   }

}
Run Code Online (Sandbox Code Playgroud)

=>

$g++ -std=c++11 -o main *.cpp
$main
A
A
Run Code Online (Sandbox Code Playgroud)

Typ*_*ats 5

让我们看看你的代码:

vector<A> v;
v.push_back(B());
v.push_back(C());
Run Code Online (Sandbox Code Playgroud)

在这里,push_back接受一个类型的参数A&&并使用 的移动构造函数移动它A,以构造向量的新元素。所以,你的代码:

  1. 创建As的向量
  2. 构造 的实例B,然后A在该实例上调用的移动构造函数以在向量中B构造 的实例A(不是 的实例B
  3. C而不是做同样的事情B

如果要使用动态调度,则需要在向量中存储指向元素的指针。分配堆上的对象并使用 保留它们的句柄std::unique_ptr,这将释放其析构函数中的内存。

// for std::unique_ptr, available since C++11, and std::make_unique, available since C++14
#include <memory>

// ...

std::vector<std::unique_ptr<A>> v;
v.push_back(std::make_unique<B>());
v.push_back(std::make_unique<C>());
Run Code Online (Sandbox Code Playgroud)

既然向量使用了std::unique_ptr,那么&在遍历向量时需要使用:

for(auto& x : v) {
    std::cout << x->print() << std::endl;
}
Run Code Online (Sandbox Code Playgroud)

auto不会自动放置引用。如果只是使用auto,那么vector的每一个元素都会被复制到 中x,但是因为std::unique_ptr删除了 的复制构造函数,代码将无法编译。