2
\$\begingroup\$

Requirements

The code should be able to call a parent method to read and modify child object variable that is referenced by a pointer inside the Child class. This code is to be run on an embedded environment, so memory and performance requirements must be addressed.

Application

The proposed solutions allows a parent class to have access to the child class variables. If for an example we have a class Player that inherits classes Stats and Events. The class Player loads stats using methods from class Stats. Then when an event occurs it will trigger a method inside Events class which will read and modify stats from a variable that is declared in its child class Player.

Solution 1

Using a virtual method in a parent class and implement it in a child class will allow it to be called in a parent class and in-turn be able to get the required object.

Example A. Using one parent class

#include <iostream>

class Life {
    public:
    int meaning;
    Life(){
        meaning = 42;
    }
};

class parentClassA {
    public:
        virtual Life* getLife();
        void printMeaningOfLife() {
            Life* A = this->getLife();
            std::cout << A->meaning << std::endl;
            A->meaning = 9001;
        }

};

class childClass : public parentClassA {
    public:
        Life* A;
        childClass() {
            A = new Life;
        }
        Life* getLife() {
            return this->A; 
        }
};

int main()
{
    childClass c;
    c.printMeaningOfLife();
    std::cout << c.A->meaning << std::endl;
    return 0;
}

Example B. Using multiple parent classes

    #include <iostream>

class Life {
    public:
    int meaning;
    Life(){
        meaning = 42;
    }
};

class parentClassA {
    public:
        virtual Life* getLife()=0;
        void printMeaningOfLifeA() {
            Life* A = this->getLife();
            std::cout << A->meaning << std::endl;
            A->meaning = 9001;
        }

};

class parentClassB {
    public:
        virtual Life* getLife()=0;
        void printMeaningOfLifeB() {
            Life* A = this->getLife();
            std::cout << A->meaning << std::endl;
        }

};

class childClass : public parentClassA, public parentClassB {
        Life* A;
    public:
        childClass() {
            A = new Life;
        }
        Life* getLife() {
            return this->A; 
        }
};

int main()
{
    childClass c;
    c.printMeaningOfLifeA();
    c.printMeaningOfLifeB();

    return 0;
}

The good

  • Does not create copies of the object
  • Accessing the object requires only one function

The bad

  • N/A

Solution 2

Passing an object pointer by reference to a function that requires it.

#include <iostream>

class Life {
    public:
    int meaning;
    Life(){
        meaning = 42;
    }
};

class parentClassA {
    public:
        void printMeaningOfLife(Life*& A) {
            std::cout << A->meaning << std::endl;
            A->meaning = 9001;
        }

};

class childClass : public parentClassA {
    public:
        Life* A;
        childClass() {
            A = new Life;
        }
};

int main()
{
    childClass c;
    c.printMeaningOfLife(c.A);
    std::cout << c.A->meaning << std::endl;
    return 0;
}

The good

  • Does not create copies of the object

The bad

  • Requires that the pointer be passed on every method between the child class and the accessing location

My conclusion

In my opinion and for my requirements I prefer the first solution. Reason being that I have 5 methods between object and accessing location which would make code readability and maintainability harder. Since the object is only referenced and not copied there should be minimal impact on memory.

The questions

  • Did I make any mistakes?
  • Can this be improved?
  • I could only think of these two solutions. Is there a different/better one?
  • What are other good and bad sides of using these two solutions?
  • Is having a requirement to access a child variable in a parent class a bad design all in itself?

Edit

Since there were no answers I'm assuming that the code and my conclusion is valid. I have also edited the code to use pure virtual functions instead of regular ones to force implementation.

\$\endgroup\$
  • \$\begingroup\$ Is this actual code used in a project, or is it merely hypothetical? \$\endgroup\$ – Sᴀᴍ Onᴇᴌᴀ Jan 5 '18 at 22:08
  • \$\begingroup\$ This is the code that I have written to solve the problem that I currently face. If there are no problems with the proposed solutions to the requirements I will implement this into my current project. \$\endgroup\$ – CodeBreaker Jan 5 '18 at 22:21
  • \$\begingroup\$ Okay - What task does this code accomplish? Please tell us, and also make that the title of the question via edit. "State what your code does in your title, not your main concerns about it.". Please read How to Ask. \$\endgroup\$ – Sᴀᴍ Onᴇᴌᴀ Jan 5 '18 at 22:23
  • \$\begingroup\$ @SamOnela Edits have been made. Unfortunately, my company prevents me to talk and publish code of developing projects so I can't tell what the actual project is and what this solves in it. \$\endgroup\$ – CodeBreaker Jan 5 '18 at 23:05

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Browse other questions tagged or ask your own question.