Reputation: 198
I have some base class and two classes derived from it. I would like to write a method for the first derived class that modifies the object's internal data by calling the already existing method of the second derived class. I want this in order to avoid making a method containing the same lines of code that I've already written for the second derived class.
Is there a safe way to do such thing? Currently, the way I do it is this:
class Base
{
protected:
int data;
// some public methods
};
class Derived1: public Base
{
private:
void ModifyData1() { data = 1; }
// some public methods
friend class Derived2;
};
class Derived2: public Base
{
public:
void ModifyData2()
{
(static_cast<Derived1 *>((Base*)this))->Derived1::ModifyData1();
}
};
So the way I understand it, the pointer this
is implicitly converted to the base pointer (upcasting) and then the static_cast
is performed on that one, to downcast to class Derived1
. This modifies the object's private variable data
, even though we called a method of another derived class.
The code seems to work, but I don't feel secure here, especially since the version with dynamic_cast
causes segmentation fault. Thanks for any advice!
UPDATE: I'm using GCC in Linux.
Upvotes: 2
Views: 243
Reputation: 42
The methods to modify the data
should be placed in the same class as data
. The parent class hold data
, it should hold modifyData()
too.
class Base {
public:
void modifYData() { data = 1}
// some other public methods
private:
int data;
};
And you'll be able to do the following:
Base b;
Derived1 d1;
Derived2 d2;
b.modifyData();
d1.modifyData();
d2.modifyData();
If you want the derived classes to behave differently when modifyDtata()
is called on them, make the method virtual and override it in them.
N.B: Read about encapsulation and access specifiers.
Upvotes: 0
Reputation: 21576
You invoked undefined Behavior with this code:
void ModifyData2()
{
(static_cast<Derived1 *>(this))->ModifyData1();
}
because the this
pointer is not a Derived1*
neither is Derived1
a base of its value type, Derived2
.
I want this in order to avoid making a method containing the same lines of code that I've already written for the second derived class.
Why don't you take that method to the base class? If you don't want to (perhaps because its not a wholistic property of all derived types) you can use an extra derived class which both Derived1
and Derived2
will inherit from.
class Base
{
protected:
int data;
// some public methods
};
class DerivedModifier : Base
{
protected:
virtual void ModifyData() { data = 1; }
};
class Derived1: public DerivedModifier
{
private:
void ModifyData1(){
DerivedModifier::ModifyData();
}
};
class Derived2: public DerivedModifier
{
public:
void ModifyData2(){
DerivedModifier::ModifyData();
}
};
Upvotes: 2