1

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

这是我当前的代码:

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();
};
4

3 回答 3

3

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

#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确保在向量超出范围时始终删除对象,即使在提前返回或异常的情况下也是如此。如需进一步参考,请参阅The Definitive C++ Book Guide 和 List

于 2013-10-12T17:13:19.447 回答
0

您不能实例化具有纯虚方法的类,即类似的方法

virtual void func() = 0;

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

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

于 2013-10-12T17:02:40.403 回答
-1

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

你可能想做的事:

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

不要忘记让你的家庭的析构函数也是虚拟的!

像这样的东西:

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
}
于 2013-10-12T17:03:45.610 回答