Question

I Have two classes:

First:

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;
    }
};

Second:

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;
    }
};

Forget private/public atributes...

I need to store some objects of base class and some objects of derived class, something like this:

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));

But in this case, functions Use(), Open(), and isOpen() will not be reachable because of slicing..

Do you have some suggestions, how to store these objects together without creating new structure of vector<Thing*> and vector<Door*>??

Thanks

Was it helpful?

Solution

A good solution to a problem when you need a container of objects with polymorphic behavior is a vector of unique pointers:

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

There would be no slicing in this situation, but you would have to figure out when it's OK to call Use(), Open(), and isOpen().

If you can move the methods from the derived class into the base, go for it; if you cannot do that because it makes no sense for a Thing to have isOpen(), consider using a more advanced solution, such as the 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);
    }
}

OTHER TIPS

Store pointers instead of instances, and declare public and protected methods as virtual in the base class(es).

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top