【问题标题】:Strange value returned from method on child object从子对象的方法返回的奇怪值
【发布时间】:2012-03-16 00:42:59
【问题描述】:

我的派生类有点问题。基本上我有一个超类Object 和一个派生类UnmovableObject。我正在尝试向派生类添加一个布尔变量,以便以后可以读取它并查看我的对象是否可以移动。我遇到的问题是我将所有对象(超级对象和派生对象)存储到list<Object> inventory 中。每次我从列表中读取值时,我都会为 isFixed() 方法得到一个奇怪的值 (204)。这是代码:

//super class
#pragma once
#include "stdafx.h"

class Object{
public:
    Object(); //constructor
    Object(const string name, const string description); //constructor
    ~Object(); //destructor
private:
    string nameOfObject; //the name of the room
    string objectDescription; //the description of the room
};

//derived class

#pragma once
#include "stdafx.h"
#include "object.h"

//This class creates unmovable objects - the user can't pick them up.
class UnmovableObject : public Object {
public:
    UnmovableObject(string name, string description);
    UnmovableObject(const Object &object)  : Object(object){};
    bool isFixed();
private:
    bool fixed;
};

//the constructor of this class takes a boolean value (by default true) - the object is fixed in this room
UnmovableObject::UnmovableObject(string name, string description) : Object(name, description){
    this->fixed = true;
}

//returns false as the object is not movable
bool UnmovableObject::isFixed(){
    return this->fixed;
}

//other class
list<Object> inventory;

我如何使用inventory.push_back(Object/UnmovableObject);,这样当我尝试访问inventory 时,我可以获得所有它们的正确布尔值——true 用于 UnmovableObject; false 为对象。

【问题讨论】:

    标签: c++ list inheritance constructor


    【解决方案1】:

    第一个问题称为切片。文你存储到Object 的列表中,只有派生类型的Object 子对象被复制。该列表将仅包含Object。如果你需要多态行为,你需要在容器中使用(智能)指针,这样对象就不会被复制(只有指针)。

    第二个问题是你不能指望获得你的类型中不存在的成员属性的值。也就是说,由于Object没有固定成员,所以无法获取其值。

    【讨论】:

    • 嗨。所以这意味着我必须修改我的所有代码,从存储和检索对象到指针?乌法,这需要一段时间。我真的希望有一个技巧可以做到这一点。谢谢
    • 不,当然可以使用更高级别的包装器来管理这种间接。在现代 C++ 中,你应该很少写 *,很少写 new,几乎从不写 delete。例如,查看boost::ptr_vector
    • @Adrian 或仅使用标准库,您可以在 C++11 中使用 shared_ptrunique_ptr 列表(共享指针也在 TR1 中。
    • @KarlKnechtel 我一直听到人们这样说——但我还没有看到很多关于它的解释。这个网站上是否有解决它的问题?或者你能给我指一本书吗?
    • @Kazark:谷歌/在 SO 中搜索智能指针及其使用。基本上使用原始指针容易出错和泄漏(几乎不可能编写使用动态分配且不使用智能指针的异常安全代码)。同时,如果您根据需要选择正确的智能指针,不会对性能产生任何影响。
    【解决方案2】:

    如果您想知道Objects 中的任何一个是否已修复,那么您真的应该让isFixed() 成为Object 类的成员。然后在派生类中覆盖它。如果您这样做,您实际上不必存储fixed 变量。此外,您应该将向量更改为指向Objects 的指针向量。

    class Object
    {
    public:
        Object(); //constructor
        Object(const string name, const string description); //constructor
        ~Object(); //destructor
        virtual bool isFixed() {return false;}
    private:
        string nameOfObject; //the name of the room
        string objectDescription; //the description of the room
    };
    
    class UnmovableObject : public Object {
    public:
        UnmovableObject(string name, string description);
        UnmovableObject(const Object &object)  : Object(object){};
        virtual bool isFixed() {return true;}
    };
    
    vector<Object*> myVector;
    

    【讨论】:

    • 嗨。函数的虚拟使用做得很好。谢谢
    猜你喜欢
    • 2018-07-10
    • 2011-05-14
    • 2019-05-24
    • 1970-01-01
    • 2012-09-21
    • 2015-11-06
    • 1970-01-01
    • 2020-10-01
    • 1970-01-01
    相关资源
    最近更新 更多