C ++将基类和派生类对象存储在一起

时间:2013-10-30 14:17:48

标签: c++ object storage base derived

我有两节课:

首先:

class Thing {
public:
    int code;
    string name;
    string description;
    int location;
    bool canCarry;

    Thing(int _code, string _name, string _desc, int _loc, bool _canCarry) {
        code = _code;
        name = _name;
        description = _desc;
        location = _loc;
        canCarry = _canCarry;
    }
};

第二

class Door: public Thing {

private:
    bool open;

public:

    int targetLocation;

    Door(int _code, string _name, string _desc, int _loc, int _targetLoc) :
            Thing(_code, _name, _desc, _loc, false) {
        open = false;
        targetLocation = _targetLoc;
    }
    void Use() {
        open = true;
    }
    void Close() {
        open = false;
    }
    bool isOpen() {
        return open;
    }
};

忘记私人/公共属性......

我需要存储基类的一些对象和派生类的一些对象, 像这样的东西:

vector < Thing*> allThings;
things.push_back(new Thing(THING1, "THING1", "some thing", LOC1, true));
things.push_back(new Door(DOOR1, "DOOR1", "some door", LOC1, LOC2));

但是在这种情况下,由于切片,函数Use(),Open()和isOpen()将无法访问..

您是否有一些建议,如何将这些对象存储在一起而不创建vector<Thing*>vector<Door*>的新结构?

由于

2 个答案:

答案 0 :(得分:6)

当您需要具有多态行为的对象容器时,问题的一个很好的解决方案是唯一指针的向量:

std::vector<std::unique_ptr<Thing>>

在这种情况下不会有任何切片,但您必须弄清楚何时可以拨打Use()Open()isOpen()

如果你可以将派生类中的方法移动到基础中,那就去吧;如果您不能这样做,因为Thing isOpen()没有任何意义,请考虑使用更高级的解决方案,例如Visitor Pattern

class Thing;
class Door;
struct Visitor {
    virtual void visitThing(Thing &t) = 0;
    virtual void visitDoor(Door &d) = 0;
};
class Thing {
    ...
    virtual void accept(Visitor &v) {
        v.visitThing(*this);
    }
};
class Door : public Thing {
    ...
    virtual void accept(Visitor &v) {
        v.visitDoor(*this);
    }
}

答案 1 :(得分:1)

存储指针而不是实例,并在基类中将public和protected方法声明为virtual。