创建子类的向量

Create a vector of sub classes?

本文关键字:向量 子类 创建      更新时间:2023-10-16

我一直在使用动态数组,但我不得不添加和删除项目。我已经读过,当可以简单地使用 std::vector 时,不建议使用 realloc 或调整数组大小,但是我在将数组更改为矢量时遇到问题。

这是我当前的代码:

int main(){
    // This is what I'm doing now
    State*arr[3];
    int pos = 0;
    arr[0] = new Menu();
    // How do I change it to a vector? This is what I'm trying:
    std::vector<State> vec;
    vec.push_back(Menu());
    ...
}

但是我不断收到错误:"无法分配抽象类型'状态'的对象"我做错了什么?


这些是类状态和菜单:

class State
{
public:
    virtual ~State() {};
    virtual void capture_events() = 0;
    virtual void logic() = 0;
    virtual void render() = 0;
};
Menu : public State
{
public:
    Menu();
    ~Menu();
    void capture_events();
    void logic();
    void render();
};

您需要额外的间接寻址State因为它是一个多态基类。您可以使用 <memory> 中的std::unique_ptr执行此操作。

#include <memory>
std::vector<std::unique_ptr<State>> states;
states.emplace_back(new Menu());

使用std::unique_ptr<State>而不是State*非常重要,因为异常安全。请考虑以下事项:

std::vector<State*> states;
states.push_back(new Menu());
foo(); // what if foo throws an exception?
       // the next line wouldn’t get executed!
for (auto ptr : states) delete ptr;

相比之下,std::unique_ptr使用 RAII 来确保在向量超出范围时始终删除对象,即使在早期返回或异常的情况下也是如此。有关进一步参考,请参阅权威C++书籍指南和列表

你不能实例化具有纯虚方法的类,即像

virtual void func() = 0;

=0意味着您必须派生类并在那里实现此方法。可以实例化此派生类。

只要一个类包含纯虚拟方法,你就不能实例化它,你就会得到你的错误。

如果使用向量,则对象必须是默认可构造的。如果其中一个虚拟方法标记为 =0 以设置类抽象,则无法构造类状态的对象。拥有一个抽象类的想法是你不能创建该类的对象

您可能想做什么:

创建一个具有抽象基础的类族,如您的状态。创建指向类的实例(对象(的指针向量。使用 new 创建对象,并push_back指向矢量的指针。如果您擦除某些元素,请不要忘记删除带有删除的对象。

不要忘记使家庭的破坏者也成为虚拟的!

像这样:

class Base
{
     virtual void Do() =0;
     virtual ~Base();
};
class A: public Base
{
     void Do() { ... }
}
class B ...
class C ...
// Create your vector somewhere...
vector<Base*> myVect;

void AddObject()
{
    // It is not important which kind of object you create. Base* obj can "hold" every
    // object which is build from a class which is derived from Base!
    Base* obj=new A();
    myVect.push_back(obj); 
}
void DeleteObj( Base* obj )
{
    myVect.erase( ...find the object...);
    delete obj;
}
void PopBack()  
{
     Base* ptr = myVect.back(); // get last object pointer 
     delete ptr;                // delete the object
     myVect.pop_back();         // remove pointer to object from vector
}