如何在允许子类方法调用的同时在C ++中实现抽象类?


How do I implement abstract classes in C++ while allowing for subclass method calls?

我创建了一个名为A的类,它有一个虚拟方法do_something

1
2
3
class A {
  virtual int do_something() = 0;
}

B亚类A

1
2
3
4
5
class B {
  virtual int do_something() {
    return 42;
  }
}

在我的主要功能中的某个地方,我这样做。

1
2
3
vector<A> arr;
arr.push_back(B());
int val = arr[0].do_something();

但是,我得到一个编译器错误,它抱怨do_something是一个纯虚拟函数。我认为这是因为我声明向量包含A类型的对象,而A是一个抽象类。因此,编译器不知道在类B中查找是否定义了do_something

有办法解决这个问题吗?我还可以存储不同类型的对象的向量吗(尽管它声明了一个公共的虚函数,但有一个公共的超类)?


通过这样声明向量:

1
vector<A> arr;

您试图创建直接类型为A的对象的向量。这不仅不允许您在其中存储B类型的对象(如果A不是抽象的,您将得到切片,当然您不希望这样做),而且它也无法编译,因为不存在A的直接实例。

这里您需要存储指向A的指针(可能是智能指针):

1
2
3
4
5
#include <memory> // For smart pointer classes

vector<shared_ptr<A>> arr;
arr.push_back(make_shared());
int val = arr[0]->do_something();

在这里,我决定使用shared_ptr,假设共享所有权,但是如果对象的唯一所有者是容器arrunique_ptr将是更好的选择。

最后,如果你真的知道你在做什么,并且你已经准备好忍受自动内存管理的麻烦,你可以使用原始指针,但是我不鼓励你这样做(你必须确保你处理delete你分配给new的每个对象):

1
2
3
vector<A*> arr;
arr.push_back(new B());
int val = arr[0]->do_something();

Is there a way around this? Can I still store a vector of objects of different types (with a common superclass though that declares a common virtual function)?

将智能指针与std::vector一起使用

1
2
std::vector<std::unique<A>> arr;
arr.emplace_back(new B());

1
arr.emplace_back(std::make_shared());