0

The title may be a little confusing but hear me out. I have this two classes , Entity and Human. Entity is the parent class of human. When I create a human object, it will require an Entity object passed as argument in the constructor so all the human objects that I create has the same Entity object info.

This is my problem: If I change some data from the Entity object I want to update all the data from the Human objects that I created using that Entity Object in the constructor.

I want to implement this in ones of my University projects so I am allowed to use only the standard library. I wrote this example so it's easier to understand:

#include <iostream>
using namespace std;

class Entity{
private:
    //DATA
    int life;
public:
    //DEFAULT CONSTRUCTOR
    Entity() {life = 100;}

    //PARAMETRIZED CONSTRUCTOR
    Entity(int life) {this -> life = life;}

    //GETTER
    int get_life(){return life;}

    //SETTER
    void set_life(int new_life){life = new_life;}

    //FUNCTIONS
    void print_life() {cout << "This entity has " << life << " life" << endl;}
};

class Human : public Entity{
public:
    //DATA
    string name;

    //DEFAULT CONSTRUCTOR
    Human() {name = "N/A";}

    //PARAMETRIZED CONSTRUCTOR
    Human(string name, Entity object){
        Entity::set_life(object.get_life());
        this -> name = name;
    }
};

int main(){
    //DATA
    Entity Human_data(50);
    Human Hero("Steve", Human_data);
    Human Villain("Mike", Human_data);

    //BODY
    Human_data.set_life(5000);
    Hero.print_life();
    
    //END MAIN
return 0;}

As you can see, after I update Human data life from 50 to 5000, it does not also change Hero and Villain life to 5000 and only changes Human data life to 5000.

8
  • 1
    Are you sure that inheritance is the right solution here? Perhaps it should be composition or something similar instead? Like saving a reference to the Entity object inside the Human object? Commented Dec 22, 2022 at 15:00
  • 1
    Or perhaps your design using a separate Human_data object is wrong, and instead you should just pass the life value itself to the Human constructor, for passing on to the Entity constructor (in aconstructor initializer list). Then just call Hero.set_life(5000) instead. What problem is supposed to be solved by having your Entity object separate and passed to the construction of the Human object? Commented Dec 22, 2022 at 15:03
  • Will all humans start with a life of 50? Commented Dec 22, 2022 at 15:04
  • I am not sure but I like your idea , can you explain a little more how I should save a reference to Entity inside Human? (I am still a noob programmer so It's a lil bit hard) Commented Dec 22, 2022 at 15:05
  • All humans start with life at 50 Commented Dec 22, 2022 at 15:06

2 Answers 2

2

I'm assuming that when you call Human_data.set_life(5000) you want to effect all Human objects constructed with the Human_data object.

Here's an example of how you might use references for that. But note putting a reference inside a class is not without consequences. You might use a pointer instead, or even better a smart pointer. But I'm just trying to indicate the general idea.

On a technical note, using references means you have to get used to using initializer lists since references cannot be assigned.

#include <iostream>
using namespace std;

class Entity{
private:
    int life;
public:
    Entity() : life(100) {}
    Entity(int life) : life(life) {}
    int get_life() {return life;}
    void set_life(int new_life){life = new_life;}
    void print_life() {cout << "This entity has " << life << " life" << endl;}
};

class Human { // no inheritence
private:
    Entity& entity; // store a reference to the entity
public:
    string name;
    Human(string name, Entity& object) // object is a reference
    : entity(object), name(name)
    {
    }
    void print_life() { entity.print_life(); } // forward to entity
};

int main(){
    //DATA
    Entity Human_data(50);
    Human Hero("Steve", Human_data);
    Human Villain("Mike", Human_data);

    //BODY
    Human_data.set_life(5000);
    Hero.print_life();

    //END MAIN
    return 0;
}
Sign up to request clarification or add additional context in comments.

2 Comments

You might want to add a note that Human_data.set_life(5000); will also apply to Villain, as it references the same Human_data object. It will, in fact, affect all Human objects referencing the same Entity object. This might be an unintended consequence.
@Someprogrammerdude I think that is the intended effect, but I'll add a note explaining that.
0

The inheritance could be correct, if all "humans" are also entities (remember that inheritance is an "is a" relationship).

But the implementation is flawed.

Instead of passing an Entity object to the Human constructor, and using the separate and distinct Entity object to control the "life", pass the life itself to the Human constructor, and use set_life on the Human object directly.

Something like this:

class Human : public Entity
{
public:
    // By default humans start out with 50 in life
    Human(std::string const& name, int life = 50)
        : Entity(life), name(name)  // Initialize the parent class, then the name
    {
    }

private:
    std::string name;
};

int main()
{
    Human hero("The Hero", 5000);  // The hero will have 5000 life
    Human villain("The Villain");  // The villain will only have 50 life

    // Some stuff...

    // Update the heroes life
    hero.set_life(4000);  // Uh oh, the hero have lost 1000 life!

    // ...
}

4 Comments

The code is reasonable but it directly contradicts what the OP says he wants.
I like your answer but it does not meet my needs. I want to implement this in another project (It creates tickets for different events). In this Ticketing app, I have the general info class and and the Ticket class (Child of general info). The user can buy 100 tickets and all the tickets has the same Info (created from an info object like movie_night_at_home that has the date set to 24.04.2022) so I will creeate ticket objects that has the same info from movie_night_at_home. If I want to change the date I can't do that for 100 objects and I need that parent class for diferent kinds of tickets
@Leonard-FlorentinSANDU Then that should have been part of the original problem description in the question itself. Please take some time to read the help pages, take the SO tour, read How to Ask, as well as this question checklist.
@Leonard-FlorentinSANDU Also note that if you save a reference, then all humans sharing that same reference will be updated. So if you use Human_data for both the hero and the villain objects, then changing the life of Human_data will change it for both hero and villain.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.