Home > other >  How to create objects that has a variable based on the data from another object that is passed in th
How to create objects that has a variable based on the data from another object that is passed in th

Time:12-23

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.

CodePudding user response:

Here's an example of how you might use references for this. 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;
}

CodePudding user response:

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!

    // ...
}
  • Related