Overriding same method in only some child classes, how to avoid duplication? - c++

I am using a base class and there are 5 child classes currently for it. Some of the functions are similar for 3 of the children but not all of them. I cannot introduce a new level of hierarchy as some methods are repeated in child 1,2,3 and some in 2,3,4.
How best can I avoid overriding the methods in all 3 children and repeating the code.

When you don't want to use multiple inheritance, you could also use composition.
Put the common code into one special class and add instances of the class to those subclasses which need the code. You then could either navigate to the functionality or wrap the call into access methods (inline).

Create a mix-in class and have the children with the method in common inherit from it also. For example:
class Base {
public:
virtual commonFunction() { /* default implementation */ };
};
class Mixin {
public:
virtual notSoCommonFunction() { /* default implementation */ };
};
class D1 : public Base {
public:
virtual commonFunction() { /* override implementation */ };
};
class D2 : public Base, public Mixin {
public:
virtual commonFunction() { /* override implementation */ };
virtual notSoCommonFunction() { /* override implementation */ };
};
class D3 : public Base, public Mixin {
public:
virtual commonFunction() { /* override implementation */ };
virtual notSoCommonFunction() { /* override implementation */ };
};
So all classes D1, D2, D3 implement (and optionally override) commonFunction, but only D2 and D3 implement (and optionally override notSoCommonFunction).

You could add a new intermediate class with protected methods for the different implementations of each function. Then in the child classes override the methods from the original base class and call the appropriate protected methods from this new intermediate class.
class Base {
public void foo() { /* ... */ }
public void bar() { /* ... */ }
}
class Middle extends Base {
protected void foo1() { /* ... */ }
protected void foo2() { /* ... */ }
protected void bar1() { /* ... */ }
protected void bar2() { /* ... */ }
}
class Child1 extends Middle {
// Use default foo()
public void bar() { bar1(); }
}
class Child2 extends Middle {
public void foo() { foo1(); }
public void bar() { bar2(); }
}
class Child3 extends Middle {
public void foo() { foo2(); }
// Use default bar()
}

Or you could explore Strategy pattern. Sometimes, HAS-A relation is better choice than IS-A. Of course, I don't know if your problem allows introduction of the pattern

Most of the answers above talk of using a new class, but the method I am using calls many other methods of the class and also uses some of the class instance variables. If I use a mixin or compose a new class, I wont be able to implement the method.

If you need access to the other members of the class, you could use templated mixins that static_cast the this pointer to the appropriate type:
template<class T>
class M1Mixin {
public:
int m1() {
return static_cast<T*>(this)->some_value;
}
};
class Base {
public:
int some_value;
...
};
class A : public Base, M1Mixin<A> {
...
};
It's not pretty, but it works.

The code review can wait before you get the satisfactory answer for this, right? Cool. :-)

Another solution that might work is the following:
Suppose that the base class is called MyBaseClass, the child classes are ChildClass1 through ChildClass5, and the function that you want to duplicate looks like this:
public int foo(Object args)
{...}
Now what you can do is create a separate class (call it "HelperFunctions" or some such) with a static method:
public static int fooHelper(BaseClass theClass, Object args)
{insert duplicated code here}
and then have the foo functions in the classes you want call that helper function.
This has a few advantages:
You're not creating new objects or changing the type hierarchy. Since the helper function is static you can call it without needing any new objects.
You can still call methods of the class, because you are passing in the object of type BaseClass, so you can call methods on it just like you would from within the class.
Most of the answers above talk of using a new class, but the method I am using calls many other methods of the class and also uses some of the class instance variables. If I use a mixin or compose a new class, I wont be able to implement the method.
I'm not sure I understand what the problem is. At least in my solution, you're passing in the object, so you can call whatever methods and access instance variables on the object you want. Is the problem that the instance variables or methods you want to access are private so you can't access them outside the class? In that case you can easily solve it by declaring the helper function to be a friend function (just google "c++ friend function" for tutorials on how to use them)

Related

Allow descendant to call overridden protected function on instance of another descendant

Suppose we have a base class Base with a public interface, and some protected methods that are used to support the public interface. Simplified example:
class Base {
protected:
virtual int helper() const = 0;
public:
virtual void do_work() {
//By default, just call the helper. Descendants can customize behaviour.
int x = helper();
do_something_with_an_int(x);
}
};
And suppose we have some descendants DerivedA, DerivedB, DerivedC ... that implement this interface.
The reason I want to split up the work in two functions (rather than just use do_work to do everything) is because I want to have a special descendant that might look something like this:
class DescendantWrapper : Base {
Base *impl;
int x;
protected:
int helper() const override {
x += impl->helper();
}
public:
void do_work() override {
helper();
if(some_internal_condition()) {
do_some_other_thing_with_an_int(x);
} else {
x = 0;
}
}
};
The intention is to allow DescendantWrapper to wrap any descendant of Base, and take the place of that descendant in some other code. Of course, the other code would not be aware that its descendant of Base has been wrapped.
The problem is that a derived class (in this example, DescendantWrapper) cannot call a protected method on an instance of its parent class (in this example, Base::helper()).
One solution is to specifically declare DescendantWrapper as a friend of Base. However, this means that other users of this code couldn't create their own descendant wrappers. Does anyone know an alternative to friend functions in this scenario?

Implement all virtual methods but change only some of them

I want to declare all Base virtual functions in Derived for future reference. I don't mind the default Base behavior but I will probably want to customize some of them later in Derived. What's the best way to do it? So far I'm doing it like this:
class Base {
virtual void fun1(){ /*default behavior*/ };
virtual void fun2(){ /*default behavior*/ };
virtual void fun3(){ /*default behavior*/ };
//more methods here
}
class Derived : public Base {
virtual void fun1() override { Base::fun1(); /* may be customized later */ };
virtual void fun2() override { /*specific implementation for derived here*/ };
virtual void fun3() override { Base::fun3(); /* may be customized later */ };
//rest of the base virtuals here
}
Is it a good practice or is it better to omit unchanged methods?
It is better to omit unchanged methods. And it is definitely not good practice to use the override keyword when the behavior of the method is not changing.
I would suggest using comments if you want to explicitly tell the user that the functions do in fact exist in the base class and they may be modified, but that you aren't changing them for the time being.
As another user suggested, you could have an inheritance chain whereby each level of inheritance overrides more methods from the base class. This would be a clear way to do it. Something like this:
class Base { /* ... */ };
class Derived1 : public Base { /* override a method from Base */ };
class Derived2 : public Derived1 {/* override a different method from Base */ };

Can you force classes inheriting from abstract base class to only have the public methods defined in base case?

Is it possible to have an abstract class but FORCE implementing classes to have only the public methods that are in the abstract class?
I don't care how the private methods work, but I want to force the classes to have only one public method.
For example, say I have the following abstract class:
class MyObjectTransform
{
public:
virtual ~MyObjectTransform()
{
}
virtual MyObject transform(MyObject input) = 0;
};
Then I want to force all objects inheriting from MyObjectTransform to ONLY have a single (other than the constructor) public method, transform. I don't care what private methods the inheriting classes have. Is this possible?
Update:
The goal here is to force the developer to only expose functionality through a single method. For example, consider this situation:
class ATransform
{
private:
MyObject A_Stuff(MyObject input);
public:
override MyObject transform(MyObject input)
{
return this->A_stuff(input);
}
};
class BTransform
{
public:
MyObject B_Stuff(MyObject input);
override MyObject transform(MyObject input)
{
return this->B_stuff(input);
}
};
The problem here is that the dev can call B_Stuffdirectly. I want to prevent this.
No you can't. Derived classes can define any public member functions they want. There is no way to put a constraint on that.
Update:
Declare B_Stuff as private if you don't want that users access it. Declare it as protected if you want that classes derived from BTransform can also use it.
class BTransform
{
private:
MyObject B_Stuff(MyObject input);
Public:
override MyObject transform(MyObject input)
{
return this->B_stuff(input);
}
};
But you can't force with the C++ language to declare B_Stuff as private or protected. It must be defined as a policy.
You are already using the mechanism that is in place for this scenario: it's the abstract base class!
The whole point of it is that all classes in this hierarchy are meant to support being used polymorphically through a pointer/reference to the base class MyObjectTransform. This way the user does not know what public methods the implementing class has because he can only use the one available through the base class: transform.
If you want to enforce this slightly more strictly, don't expose the declaration of the implementing classes in a header at all. Hide BTransform and ATransform, and expose only factory functions along with the abstract base class.
std::unique_ptr<MyObjectTransform> makeATransform()
{
return { new ATransform };
}
std::unique_ptr<MyObjectTransform> makeBTransform()
{
return { new BTransform };
}
This way the client/developer code looks like this:
int main()
{
auto btransform = makeBTransform();
btransform->B_Stuff(input); // ERROR, MyObjectTransform doesn't have this member function.
btransform->transform(input); // FINE
}
Users can only use the one public method in the base class.
Ofcourse someone could cast the pointer to a BTransform*, and then do anything they want (provided they could find out what the actual implementation of BTransform is, since we hid it). But then theres no bypassing the fact that to prevent public methods from being accessible you have to make them private, like chmike wrote. As Herb Sutter said:
C++ protects against Murphy, not Machiavelli
In C++, public functions should be non-virtual and virtual functions should be private (with the exception of the destructor). Applying this guideline makes your problem disappear entirely, because there is only one public function left for clients of the class to call:
class MyObjectTransform
{
public:
virtual ~MyObjectTransform()
{
}
MyObject transform(MyObject input) // non-virtual!
{
// can do extra stuff, e.g. check input for validity
doTransform(input);
}
private:
virtual MyObject doTransform(MyObject input) = 0;
};
class ATransform : public MyObjectTransform
{
private:
MyObject A_Stuff(MyObject input);
MyObject doTransform(MyObject input) override
{
return this->A_Stuff(input);
}
};
class BTransform : public MyObjectTransform
{
private:
MyObject B_Stuff(MyObject input);
MyObject doTransform(MyObject input) override
{
return this->B_Stuff(input);
}
};

Executing base function before continuing in derived function

I'm trying to solve a problem where I have some classes in which I need to do some common work and then a bunch of problem specific work and when this is finished do some more processing common to all these classes.
I have a Base and Derived class that both have a function called Execute. When I call the derived version of this function, I'd like to be able to do some processing common to all my derived classes in the Base and then continue executing in my Derived::Execute and going back to Base::Execute to finish off with some common work.
Is this possible in C++ and how would one best go about doing that?
This is the idea, however it's probably not very workable like this:
class Base
{
public:
virtual void Execute();
};
Base::Execute() {
// do some pre work
Derived::Execute(); //Possible????
// do some more common work...
}
class Derived : public Base
{
public:
void Execute();
};
void Derived::Execute()
{
Base::Execute();
//Do some derived specific work...
}
int main()
{
Base * b = new Derived();
b.Execute(); //Call derived, to call into base and back into derived then back into base
}
Use a pure virtual function from base..
class Base
{
public:
void Execute();
private:
virtual void _exec() = 0;
};
Base::Execute() {
// do some common pre work
// do derived specific work
_exec();
// do some more common work...
}
class Derived : public Base
{
private:
void _exec() {
// do stuff
}
};
int main()
{
Base * b = new Derived();
b.Execute();
}
EDIT: changed the flow slightly after reading the question some more.. :) The above mechanism should match exactly what you require now -
i.e.
Base Common Stuff
Derived specific stuff
Base Common stuff again
This is called the NVI (Non-Virtual Interface, from Herb Sutter here) idiom in C++, and basically says that you should not have public virtual functions, but rather protected/private virtual functions. User code will have to call your public non-virtual function in the base class, and that will dispatch through to the protected/private virtual method.
From a design perspective the rationale is that a base class has two different interfaces, on one side the user interface, determined by the public subset of the class, and on the other end the extensibility interface or how the class can be extended. By using NVI you are decoupling both interfaces and allowing greater control in the base class.
class base {
virtual void _foo(); // interface to extensions
public:
void foo() { // interface to users
// do some ops
_foo();
}
};
Turn the problem from its head to its feet. What you actually want to have is a base class algorithm that derived classes can plug into:
class Base {
public:
void Execute()
{
// do something
execute();
// do some more things
}
private:
virtual void execute() = 0;
};
class Derived : public Base {
public:
// whatever
private:
virtual void execute()
{
//do some fancy stuff
}
};
Letting derived classes plug into base class algorithms is often called "template method" pattern (which has nothing to do with template. Having no public virtual functions in the base class interface is often called "non-virtual interface" pattern.
I'm sure google can find you a lot on those two.
Move that Base::Execute internally in two functions and then use RAII to implement that easily.
class Base{
protected:
void PreExecute(){
// stuff before Derived::Execute
}
void PostExecute(){
// stuff after Derived::Execute
}
public:
virtual void Execute() = 0;
};
struct ScopedBaseExecute{
typedef void(Base::*base_func)();
ScopedBaseExecute(Base* p)
: ptr_(p)
{ ptr_->PreExecute() }
~ScopedBaseExecute()
{ ptr_->PostExecute(); }
Base* ptr_;
};
class Derived : public Base{
public:
void Execute{
ScopedBaseExecute exec(this);
// do whatever you want...
}
};

How to easily substitute a Base class

I have the following hierarchy of classes
class classOne
{
virtual void abstractMethod() = 0;
};
class classTwo : public classOne
{
};
class classThree : public classTwo
{
};
All classOne, classTwo and classThree are abstract classes, and I have another class that is defining the pure virtual methods
class classNonAbstract : public classThree
{
void abstractMethod();
// Couple of new methods
void doIt();
void doItToo();
};
And right now I need it differently...I need it like
class classNonAbstractOne : public classOne
{
void abstractMethod();
// Couple of new methods
void doIt();
void doItToo();
};
class classNonAbstractTwo : public classTwo
{
void abstractMethod();
// Couple of new methods
void doIt();
void doItToo();
};
and
class classNonAbstractThree : public classThree
{
void abstractMethod();
// Couple of new methods
void doIt();
void doItToo();
};
But all the nonAbstract classes have the same new methods, with the same code...and I would like to avoid copying all the methods and it's code to every nonAbstract class. How could I accomplish that?
Hopefully it's understandable...
template<class Base>
struct Concrete : Base {
void abstractMethod();
void doIt() {
// example of accessing inherited members:
int n = Base::data_member; // or this->data_member
n = Base::method(); // non-virtual dispatch
n = this->method(); // virtual dispatch
// since Base is a template parameter, 'data_member' and 'method' are
// dependent names and using them unqualified will not properly find
// them
}
void doItToo();
};
typedef Concrete<classOne> classNonAbstractOne; // if desired, for convenience
Make sure to give your abstract base classes either a virtual public destructor or make the destructor protected (then it doesn't have to be virtual, but still can be).
Because the template must be parsed with names looked up without yet knowing exactly what Base will be, you need to either use Base::member or this->member to access inherited members.
I usually try to avoid inheritance if possible (except for pure abstract classes which define pure interfaces) because it creates a tight coupling. In many cases composition is the better alternative.
Also, things tend to get messy with complex inheritance structures. It's not easy to say from your description what's the best in this particular case. Just pointing this out as a rule of thumb.