-1

I want to first create an object of a parent class and according to some condition create child object of child class and put that into parent object. Now while after passing the object to some function that function need to get access to child class method. Please see the code for clarification.

class Parent {
    virtual f(){
        print('Parent');
    }
}

class Child: public Parent{
    virtual f(){
        print('Child')
    }
}

void do_something(Parent &obj){
    obj.f(); // this will print Child
}

int main(){

    Parent obj;
    if(cond){
        // This is my actual question
        // Not sure how to create a child obj here and put it into parent obj
        Child obj = dynamic_cast<Child>(obj);
    }   

    do_something(obj) // pass the child obj
}
shanto
  • 47
  • 7
  • 1
    That is not how polymorphism works. You can't magically change `obj` from being an instance of `Parent` to being an instance of `Child`, it needs to be a `Child` from the beginning, eg: `Child obj;` Maybe you want this instead: `Parent *obj; if (cond) { obj = new Child; } else { obj = new Parent; } do_something(*obj); delete obj;` Either way, your `do_something()` needs to be more like this: `void do_something(Parent &obj) { obj.f(); }` – Remy Lebeau Feb 05 '19 at 23:29
  • 1
    `f(); // this will print Child`. `f` is undeclared in such context. Did you mean `obj.f ();`? Even if you did, it won't print that, due to [object slicing](https://stackoverflow.com/questions/274626/what-is-object-slicing). – Algirdas Preidžius Feb 05 '19 at 23:29
  • Yes it should be obj.f() – shanto Feb 05 '19 at 23:32
  • 1
    What do you mean by "put into a parent object"? I don't understand. – eerorika Feb 05 '19 at 23:42
  • @eerorika please see the code for better understanding. Thanks. – shanto Feb 05 '19 at 23:44
  • 1
    @shanto I see the code. Besides the numerous other reasons why the program is ill-formed, you cannot dynamic cast an object. It is unclear to my what you're trying to achieve by doing that. – eerorika Feb 05 '19 at 23:46
  • @eerorika I wanted to create some object in runtime based on some condition not in compile time. – shanto Feb 05 '19 at 23:48
  • 1
    @shanto here you go: `if(condition) { Child c; } else { Parent p; }` – eerorika Feb 05 '19 at 23:50
  • @eerorika if the objects are created in if block then I can't pass them to do_something(), right? – shanto Feb 05 '19 at 23:52
  • 1
    @shanto You can call `do_something` within the block. – eerorika Feb 05 '19 at 23:52
  • @eerorika that might work but I didn't want to call do_something from each block. :) – shanto Feb 05 '19 at 23:54

1 Answers1

2
  1. Use a pointer instead of an object.

    Parent* ptr = nullptr;
    if(cond){
        ptr = new Child();
    }
    
    if ( ptr )
    {
       do_something(*ptr) // pass the child obj
    }
    
  2. Change do_something to use a reference, not an object. When the argument is passed by value of the object, the program suffers from the objct-slicing problem.

    void do_something(Parent& obj){
      ....
    }
    
  3. Change do_something to call f() on the passed object.

    void do_something(Parent& obj){
      obj.f();
    }
    
R Sahu
  • 204,454
  • 14
  • 159
  • 270
  • 1
    @shanto, you can create an object of type `Child` and use it directly instead of assigning it to `obj`. You still have to change `do_something`. – R Sahu Feb 05 '19 at 23:37
  • @Sahu the problem is based on the condition I might need to create another object of another class ex. Child2 which would also be a subclass of Parent and vice versa. – shanto Feb 05 '19 at 23:41
  • 1
    @shanto, pick the solution that makes most sense to you. 1. Use a pointer and have one line of call to `do_something`. .2. Use objects and have multiple lines that call `do_something`. I don't see another alternative. – R Sahu Feb 05 '19 at 23:45