指针的多态性

时间:2012-04-25 16:39:53

标签: c++ constructor polymorphism

我使用的是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的指针,并分配给新的//我认为这是问题发生的地方

然后该指针的引用被推送到经理成员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);
};

编辑:更改背景以更好地定位手头的问题,并获得解决方案

3 个答案:

答案 0 :(得分:1)

指针值仅在构造函数完成后更改,这不是问题。这是合乎逻辑的,因为首先对一个临时指针起作用,只将它指定给你的指针。

答案 1 :(得分:1)

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

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

vec.push_back(newObject);

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

答案 2 :(得分:0)

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

也许最好从实际工作的东西开始,添加你需要的功能,或者至少了解你偏离预期/有效的地方。所以,这是一个动态创建对象的小样本,将它们放入ptr_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

对于它的价值,请注意析构函数 - 当Object被销毁时,只调用基本dtor,但是当Entity被销毁时,首先调用派生的dtor,然后调用调用base dtor(所以我们看到'Entity被销毁'和'Object被销毁')。