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

Maj*_*jak 3 c++ storage derived base object

我有两节课:

第一:

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;
    }
};
Run Code Online (Sandbox Code Playgroud)

第二:

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;
    }
};
Run Code Online (Sandbox Code Playgroud)

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

我需要存储基类的一些对象和派生类的一些对象,如下所示:

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));
Run Code Online (Sandbox Code Playgroud)

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

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

谢谢

das*_*ght 6

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

std::vector<std::unique_ptr<Thing>>
Run Code Online (Sandbox Code Playgroud)

会有在这种情况下没有分层,但你必须弄清楚时,它的确定以打电话Use(),Open()isOpen().

如果你可以将派生类中的方法移动到基础中,那就去吧; 如果你不能这样做,因为它是没有意义的ThingisOpen(),可以考虑使用更先进的解决方案,如访问者模式:

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);
    }
}
Run Code Online (Sandbox Code Playgroud)