-1

Concerning to Inheritance, I want to create concrete Objects from Base Class. As I understand, the Child class can represent it's father class. Considering following classes:

class Material{
    public:
    virtual void print(){
        cout << "Base Material Class" << endl;
    }
}

class Wood: public Material{
    public:
    void print(){
        cout << "Wood Material" << endl;
    }
}

class Furniture{
    public:
    void setMaterial(Material material){
        this->material = material;
    }
    virtual void print(){
        this->material.print();
    }
    protected:
        Material material;
}

class Chair: public Furniture{
// further code implements here
}

int main(int argc, char** argv){
     Chair aChair;
     Material material = Wood();
     aChair.setMaterial(material);
     aChair.print(); // -> "Base Material Class"
}

The question is how to specify material as Wood/Steel/etc... in runtime (This is available in Java but Cpp is not Java). Do you have any suggestion?. I had a look at here and here but I still have not found the solution. Thank you.

Viet Tran
  • 19
  • 4
  • 2
    Runtime polymorphism *is* available in C++. But it requires references or pointers (preferably smart pointers). You are experiencing [object slicing](https://stackoverflow.com/questions/274626/what-is-object-slicing). A decent [book on C++](https://stackoverflow.com/questions/388242/the-definitive-c-book-guide-and-list) ought to cover that. – StoryTeller - Unslander Monica Jan 03 '18 at 07:42
  • See also [What is object slicing?](https://stackoverflow.com/questions/274626/what-is-object-slicing) and [Why doesn't polymorphism work without pointers/references?](https://stackoverflow.com/questions/15188894/why-doesnt-polymorphism-work-without-pointers-references) and [Store derived class objects in base class variables](https://stackoverflow.com/questions/8777724/store-derived-class-objects-in-base-class-variables) and a zillion others. – n. m. could be an AI Jan 03 '18 at 08:00

2 Answers2

1

The line:

Material material = Wood();

doesn't allow you to use polymorphism to access a Wood instance via a base. Instead you've just sliced off part of the object.

To have polymorphism work you need to use either pointers or references. For example:

Material *material = new Wood;

NOTE: You'll want to use some pointer management class, such as shared_ptr or unique_ptr. For example.

std::shared_ptr<Material> = std::make_shared<Wood>();

and then change setMaterial to take the shared_ptr:

void setMaterial(std::shared_ptr<Material>material)
{
  this->material = material;
}

(NOTE: You'll also need to change the type of the member variable)

Sean
  • 60,939
  • 11
  • 97
  • 136
1

You have to do it with either a pointer (possibly a smart pointer) or a reference, otherwise the derived parts of any parameter are simply sliced off and all you are left with is an instance of the base type.

void setMaterial(std::shared_ptr<Material> material){
        this->material = material;
}
...
std::shared_ptr<Material> material;

Note that the member cannot be a reference if you want to be able to change the material in this way.

SoronelHaetir
  • 14,104
  • 1
  • 12
  • 23
  • The reason that a reference does not work because the program only 'sees' the base class (but not the rest part of the derived class), doesn't it? – Viet Tran Jan 03 '18 at 08:28