Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Call parent constructor with different arguments depending on child constructor argument

Is there a way to call the parent constructor with different arguments depending on the value of an argument that the child constructor has?

I have the following parent class:

class Rectangle
{
public:
    Rectangle(std::string name, glm::vec3 top_left_corner, float height, float width, glm::vec3 color, bool fill);
    ~Rectangle();
    //...
}

And the child class:

class Wall :
    public Rectangle
{
public:
    Wall(std::string name, Position position, float scene_height, float scene_width, float thickness, glm::vec3 color);
    ~Wall();
    //...
}

Where Position is an enum that should dictate what arguments the parent constructor should be called with:

enum Position { UP, DOWN, LEFT, RIGHT };

So basically, I would like to have something like this in the child constructor:

Wall::Wall(std::string name, Position position, float window_height, float window_width, float thickness, glm::vec3 color) {
    switch(position) {
    case UP:
        Rectangle(name, glm::vec3(0, window_height, 0), thickness, window_height, color, true);
        break;
    case DOWN:
        Rectangle(name, glm::vec3(0, thickness, 0), thickness, window_width, color, true);
        break;
    case LEFT:
        Rectangle(name, glm::vec3(0, window_height, 0), window_height, thickness, color, true);
        break;
    case RIGHT:
        Rectangle(name, glm::vec3(0, window_width - thickness, window_height), window_height, thickness, color, true);
        break;
    }
}

But as you know, I have to call the parent constructor first, like:

Wall::Wall(std::string name, Position position, float window_height, float window_width, float thickness, glm::vec3 color)
    : Rectangle(name, glm::vec3(0, window_width - thickness, window_height), window_height, thickness, color, true) {}

And that doesn't give me much leeway. What would a good, object-oriented approach be?

like image 364
SakoDaemon Avatar asked Oct 28 '18 12:10

SakoDaemon


People also ask

How do you call parent constructor in child constructor?

In order to run a parent constructor, a call to parent::__construct() within the child constructor is required. If the child does not define a constructor then it may be inherited from the parent class just like a normal class method (if it was not declared as private). $obj = new OtherSubClass();

Does a child constructor always invoke a parent constructor?

If parent class implements a constructor with arguments and has no a constructor with no arguments, then the child constructors must explicitly call a parents constructor.

Can we call parent constructor from child if parent constructor contain parameter?

The answer is: you can't! In case the super class has a parameter free constructor, the compiler can add one like that for you in subclass, too.

How do you call a constructor of parent class in child class?

Super keyword in javascript: By executing the super() method in the constructor method, we invoke the constructor method of the parent and get access to the parent's properties and methods. we can only use the super keyword in the child class of a parent class.


1 Answers

Create a factory method:

Rectangle MakeRectangle(const std::string& name,
                        const Position& position,
                        float window_height, float window_width,
                        float thickness,
                        const glm::vec3& color)
{
    switch(position) {
    case UP:
        return Rectangle(name,
                         glm::vec3(0, window_height, 0),
                         thickness,
                         window_height,
                         color,
                         true);
    case DOWN:
        return Rectangle(name,
                         glm::vec3(0, thickness, 0),
                         thickness,
                         window_width,
                         color,
                         true);
    case LEFT:
        return Rectangle(name,
                         glm::vec3(0, window_height, 0),
                         window_height,
                         thickness,
                         color,
                         true);
    case RIGHT:
        return Rectangle(name,
                         glm::vec3(0, window_width - thickness,  window_height),
                         window_height,
                         thickness,
                         color,
                         true);
    }
    throw std::runtime_error("Invalid position");
}

Then

Wall::Wall(std::string name,
           Position position,
           float window_height, float window_width,
           float thickness,
           glm::vec3 color)
: Rectangle(MakeRectangle(name, position, window_height, window_width, thickness, color)){
// ...
}
like image 69
Jarod42 Avatar answered Sep 28 '22 14:09

Jarod42