-1

我正在使用 a boost::ptr_vector,但我相信这也适用于标准std::vector。我正在尝试将指向对象的指针多态地放入boost::ptr_vector层次结构中,因为我有一个Entity继承自Object使用该行创建的对象

Object * newObject = new Entity(param1, param2);  // then I attempt to add it to the ptr_vector

但是如果我打破程序(Visual Studio 2010)来查看正在保存的内容,则指针永远不会从垃圾中重定向,并且垃圾正在被保存。我单步执行代码,它确实进入了参数化构造函数,并遵循正确的逻辑步骤。

我不确定出了什么问题。我是否需要在父级或子级中具有特定的成员函数才能使这种多态行为起作用(当前所有子级都具有其类型独有的参数化构造函数,以及析构函数以及多态交互方法)。我必须有赋值运算符,还是应该在Object类中有构造函数。

似乎对运算符的调用new不是解析为对象,而是解析为其他内容,但 VS2010 并没有引发错误。


编辑:解释应该发生的事情。

穿过 2D std::vector(矩形/非锯齿状)

用于case/switch确定要生成的对象,并添加到结构中

创建指向 Object 的指针,并分配给 new // 我认为这就是问题所在

然后将该指针的引用推送到管理器成员boost::ptr_vector

在 Visual Studio 2010 中,我在创建指针的行处放了一个断点,并分配新的(多态的)和一个用于观察指针的push_back()boost::ptr_vector。临时指针值被创建,并进入构造函数,它遵循该构造函数的所有逻辑步骤,当构造函数完成时,堆栈返回到调用构造函数的行,指针仍然是相同的值(我认为这是可接受),但是当我查看它指向的对象时,所有值都显示为问号(包括静态组合的成员对象)。然后当推回触发并进入 boost-header 时,该x值显示相同的信息。

似乎正在创建指针,并且创建了对象的数据,但是一旦构造函数完成,它实际上并没有将值分配给父类对象,这对于多态行为应该相当简单。

关注的示例标头(真正的标头确实具有成员变量,并且它们的实现位于单独的 cpp 文件中):

class Object{
public :
    virtual void interact(int action, Object& source){}
    virtual void updateObject(float duration){}
    virtual ~Object(){}
    bool operator==(const Object& _other)const;
    bool operator!=(const Object& _other)const;
};

class Entity : public Object{
public:
    Entity(Vector3 location, Type thisType, SpecialType difficulty=noSpecial);
    ~Entity();
    void interact(int action, Object& source);
    void updateObject(float duration);
};

编辑:更改上下文以更好地解决手头的问题,并获得解决方案

4

3 回答 3

1

指针值只有在构造函数完成才会改变,这不是问题。这是合乎逻辑的,因为首先对临时指针进行操作,并且仅将它分配给您的指针。

于 2012-04-25T16:44:37.870 回答
1

Object * newObject = new Entity(param1, param2);

您将newObject指向新创建的对象。虽然构造函数正在运行,newObject但仍未分配。如果你之后有

vec.push_back(newObject);

您可以进入该push_back方法并查看参数是Object具有引用Entity方法的虚拟表。(你至少有一个虚拟析构函数,对吧?)

于 2012-04-25T18:07:29.713 回答
0

根据您发布的内容,很难(如果可能的话)确定问题,更不用说它是如何发生的/如何解决它。

也许最好从实际可行的东西开始,并添加您需要的功能,或者至少了解您偏离预期/有效的地方。因此,这里有一个动态创建对象的小示例,将它们放入 aptr_vector中,在每个对象中使用一个虚函数来验证容器中的内容是否符合预期,然后让容器超出范围(在此过程中,销毁它包含的指针引用的对象)。

#include "boost/ptr_container/ptr_vector.hpp"
#include <iostream>
#include <string>
#include <sstream>

class Object { 
    std::string name;
public:
    Object(std::string const &n) : name(n) {}

    virtual std::ostream &write(std::ostream &os) const {
        return os << name;
    }

    virtual ~Object() { std::cout << "Object being destroyed\n"; }
};

class Entity : public Object { 
    int value;
public:
    Entity(int v, std::string name) : Object(name), value(v) {}

    std::ostream &write(std::ostream &os) const { 
        return os << "Entity: " << value;
    }
    ~Entity() { std::cout << "Entity being destroyed\n"; }  
};

int main() { 
    boost::ptr_vector<Object> objects;

    for (int i=0; i<10; i++) {
        std::stringstream name;
        name << "object: " << i;
        if (i & 1)
            objects.push_back(new Object(name.str()));
        else
            objects.push_back(new Entity(i, name.str()));
    }

    boost::ptr_vector<Object>::iterator pos;
    for (pos = objects.begin(); pos != objects.end(); pos++) {
        pos->write(std::cout);
        std::cout << "\n";
    }
    return 0;
}

至少对我来说,输出看起来像这样:

Entity: 0
object: 1
Entity: 2
object: 3
Entity: 4
object: 5
Entity: 6
object: 7
Entity: 8
object: 9
Entity being destroyed
Object being destroyed
Object being destroyed
Entity being destroyed
Object being destroyed
Object being destroyed
Entity being destroyed
Object being destroyed
Object being destroyed
Entity being destroyed
Object being destroyed
Object being destroyed
Entity being destroyed
Object being destroyed
Object being destroyed

对于它的价值,请注意析构函数 - 当 anObject被销毁时,仅调用基本 dtor,但是当 anEntity被销毁时,首先调用派生 dtor,然后调用基本 dtor(所以我们看到两个'实体被销毁' 和 '对象被破坏")。

于 2012-05-04T14:30:43.673 回答