-2

I want use child pointer in place of parent parameter in some function. Here is simplified code

#include <iostream>
#include <string>
using namespace std;
class Parent
{
    private:
        string value;
    public:
        void SetValue(const string& in){ value = in; }
        const string& GetValue() const { return value; }
        virtual ~Parent() {};
};
class Child : public Parent
{
};
void Func(Parent* obj)
{
    Child* cobj = dynamic_cast<Child*>(obj);
    cobj->SetValue("new value");
    delete cobj;
}
int main(int argc, char** argv)
{
    Child* cobj = new Child();
    Func(cobj);
    cout<<"value: "<<cobj->GetValue();
    return 0;
}

But it returns value:
Func does not set the value property. How can I fix the code?
UPDATE1:
But with this code:

#include <iostream>
#include <string>
using namespace std;
class Parent
{
    private:
        string value;
    public:
        void SetValue(const string& in){ value = in; }
        const string& GetValue() const { return value; }
        virtual ~Parent() {};
};
class Child : public Parent
{
    private:
        int number;
    public:
        void SetNumber(int in){ number = in; }
        int GetNumber() const { return number; }
};
void Func(Parent* obj)
{
    Child* cobj = dynamic_cast<Child*>(obj);
    cobj->SetValue("new value");
    cobj->SetNumber(100);
    delete cobj;
}
int main(int argc, char** argv)
{
    Child* cobj = new Child();
    Func(cobj);
    cout<<"value: "<<cobj->GetValue()<<endl;
    cout<<"number: "<<cobj->GetNumber()<<endl;
    return 0;
}

I get value: number: 100
Why SetNumber work but SetValue does not?

JalalJaberi
  • 2,417
  • 8
  • 25
  • 41
  • 1
    You have undefined behavior here as you delete the object inside `Func` but then use it in `main` - the `dynamic_cast` doesn't give you a new instance. Your whole code "feels wrong" - if you are doing OO properly you don't need the `dynamic_cast` at all... – John3136 Jul 01 '18 at 23:33
  • @John3136 Doesn't SetValue() affect `Parent* obj`? because obj and cobj refer to the same location? – JalalJaberi Jul 01 '18 at 23:37
  • 2
    @JalalJeberi Yes it does. But in `Func` you `delete cobj;` so now it doesn't exist anymore. – John3136 Jul 01 '18 at 23:40
  • @John3136 I don't need that `cobj` in `Func` body. `obj` and outer `cobj` both hold the pointer to the same location. I have updated the question. What about the `SetNumber`? – JalalJaberi Jul 01 '18 at 23:47
  • 2
    Undefined behavior is undefined. You don't understand dynamic memory allocation. You are deleting the object being pointed to, not "the pointer" - the pointer still has a value, but now what it points to is "gone" – John3136 Jul 01 '18 at 23:51

2 Answers2

1

Your problem has nothing to do with inheritance or function parameters. The problematic code can be reduced to:

Child* cobj = new Child();
cobj->SetValue("new value");
delete cobj;
cobj->GetValue();

The last two lines are the problem. delete cobj destroys the object, but cobj->GetValue() still tries to use it. This code has undefined behavior.

To fix the code, you need to remove either delete cobj or the GetValue() call. In any case, don't try to use an object after it has been destroyed.

melpomene
  • 84,125
  • 8
  • 85
  • 148
1

You delete the object and then continue to access it. This causes undefined behaviour, which means anything may happen.

You can fix the code by removing the line delete cobj;. However you should also check that the result of the dynamic_cast is not null before dereferencing it.

In case it is unclear, the delete expression deletes the object being pointed to. There is no such concept as "delete the pointer".

M.M
  • 138,810
  • 21
  • 208
  • 365