Jens Modvig
Jens Modvig

Reputation: 183

c++ Derived class changing a base class pointer

I have a user class that has a member pointer to a data class. But I want to implement a derivedUser that extends user, but it also needs to have additional data which is stored in a derivedData class, it would look something like this:

class Data {
    /*...the stored data...*/
}

class DerivedData : public Data {
    /*...the additional data...*/
}

class User {

    public:
        /*...some methods that use dp...*/

    protected:
         Data* dp;
}


class DerivedUser : public User {

    public:
        /*...even more methods that use ddp...*/

    protected:
         DerivedData* ddp;
}

But here is the problem: With the way I've set it up the DerivedUser class would store two pointers of different types pointing to the same object, which is not optimal. The DerivedUser should only store one pointer, and it should know that it is of the type DerivedData and fail if it is given the wrong type of data. And the question is: how do I implement this?

Ive tried:

class DerivedUser : public User {

    public:
        /*...even more methods that use ddp...*/

    protected:
        DerivedData* ddp = dynamic_cast<DerivedData*>(dp);
}

Upvotes: 1

Views: 998

Answers (2)

user3773246
user3773246

Reputation:

I see that you want DerivedUser to have DerivedData in its constructor.

Because of polymorphism a parent class can references it child class. So this is legal:

Data* dp = new DerivedData();

Here is the solution you are looking for:

class User {

public:
    /*...some methods that use dp...*/

    User(Data* dp){
        this->dp = dp;
    }

protected:
    Data* dp;
};

class DerivedUser : public User {

public:
    /*...even more methods that use ddp...*/

    DerivedUser(DerivedData *dp) : User(dp) {

    }
};

Now, DerivedUser points to your DerivedData class

Here:

int main(){

    DerivedData* dp = new DerivedData();

    DerivedUser* user = new DerivedUser(dp);


    return 0;
}

Upvotes: 2

Avishai Y
Avishai Y

Reputation: 123

Add a method DerivedData* GetData() in the DerivedUser class

DerivedData* GetData() { return static_cast<DerivedData>(dp); }

You can make sure dp is a DerivedData* if the constructor of DerivedUser looks like this:

DerivedUser(DerivedData* d):User(d){}

Here is the full code:

class Data {
    /*...the stored data...*/
}

class DerivedData : public Data {
    /*...the additional data...*/
}

class User {

    public:
        User(Data* d):dp(d){}
        /*...some methods that use dp...*/

    protected:
        Data* dp;
}

class DerivedUser : public User {

    public:
        DerivedUser(DerivedData* d):User(d){}
        /*...even more methods that use ddp...*/

    protected:
        DerivedData* GetData(void)
        {
            return static_cast<DerivedData*>(dp);
        };
}

Upvotes: 1

Related Questions