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)
让我们看看你的代码:
vector<A> v;
v.push_back(B());
v.push_back(C());
Run Code Online (Sandbox Code Playgroud)
在这里,push_back接受一个类型的参数A&&并使用 的移动构造函数移动它A,以构造向量的新元素。所以,你的代码:
As的向量B,然后A在该实例上调用的移动构造函数以在向量中B构造 的实例A(不是 的实例B)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删除了 的复制构造函数,代码将无法编译。