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.
Related
Let's assume you have an base class for the different states of a State Machine that has methods for different inputs like mouse, keyboard, joystick, etc. Now not every derived state is going to use all possible types of inputs. If the base class methods are pure virtual every derived state class needs to always implement every single one of them. To avoid this i declared them with an empty body in the base class and just override the ones that are used by the particular derived class. In case the class doesn't use a certain input type the empty base class method get's called. I am storing the currentState in a base class pointer and just feed it with the input without having to know which particular derived state it actually is to avoid unnessecary casts.
class Base
{
public:
virtual void keyboardInput() {}
virtual void mouseInput() {}
};
class Derived : public Base
{
public:
void keyboardInput()
{
// do something
}
// Derived doesnt use mouseInput so it doesn't implement it
};
void foo(Base& base)
{
base.keyboardInput();
base.mouseInput();
}
int main()
{
Derived der;
foo(der);
}
Is this considered a good practice?
Your question is opinion based, but I'd rather follow this approach to use an interface:
struct IBase {
virtual void keyboardInput() = 0;
virtual void mouseInput() = 0;
virtual ~IBase() {}
};
class Base : public IBase {
public:
virtual void keyboardInput() override {}
virtual void mouseInput() override {}
};
class Derived : public Base {
public:
void keyboardInput() override {
// do something
}
// Derived doesnt use mouseInput so it doesn't implement it
};
int main() {
std::unique_ptr<IBase> foo = new Derived();
foo->keyboardInput();
foo->mouseInput();
return 0;
}
Some arguments why that's better practice added from the comments:
The idea is that interface should contain as little assertions as possible, making it less likely to change, making it more dependable for those who inherit from it. Implementing the methods, albeit empty, is already an assertion, however small.
It would be less pain for refactorings coming later, which introduce more interfaces with multiple inheritance.
It really depends on what you want from the methods. When declaring an interface, usually the methods are left pure virtual because they are required to be implemented for the class to work at all. Marking them pure virtual signals "You have to implement this.".
However, sometimes there are methods that may do nothing and it's valid for all possible implementations for them to do nothing. It is not very common, but it is possible.
I don't think that your interface is the case though, and you should follow #πάντα ῥεῖ's answer. Or do it through multiple inheritance:
class MouseInput {
public:
virtual void mouseInput() = 0;
}
class KeyboardInput {
public:
virtual void keyboardInput() = 0;
}
class Derived : public KeyboardInput
{
public:
virtual void keyboardInput() override
{
// do something
}
};
class AllInput : public KeyboardInput, public MouseInput
{
public:
virtual void keyboardInput() override
{
// do something
}
virtual void mouseInput() override
{
// do something
}
};
That has the benefit that you can have methods that explicitly say that they work with one kind of input:
void doSomethingMouseIsh(MouseInput* input);
The disadvantage is that methods that combine mouse and keyboard input get weird unless you have InterfaceAllInput as interface and use it for all "all input methods"
Final note: as long as you try to write clean code, considering each use case is more important than some best practices.
If you going to be strict about it this does violate ISP (https://en.wikipedia.org/wiki/Interface_segregation_principle) as your forcing a subclass to depend on a method it doesn't use - but generally its not too bad in practice if the alternative adds more complexity.
The following code:
struct interface_base
{
virtual void foo() = 0;
};
struct interface : public interface_base
{
virtual void bar() = 0;
};
struct implementation_base : public interface_base
{
void foo();
};
struct implementation : public implementation_base, public interface
{
void bar();
};
int main()
{
implementation x;
}
fails to compile with the following errors:
test.cpp: In function 'int main()':
test.cpp:23:20: error: cannot declare variable 'x' to be of abstract type 'implementation'
test.cpp:16:8: note: because the following virtual functions are pure within 'implementation':
test.cpp:3:18: note: virtual void interface_base::foo()
I have played around with it and figured out that making the 'interface -> interface_base' and 'implementation_base -> interface_base' inheritances virtual, fixes the problem, but I don't understand why. Can someone please explain what is going on?
p.s. I omitted the virtual destructors on purpose to make the code shorter. Please don't tell me to put them in, I already know :)
You have two interface_base base classes in your inheritance tree. This means you must provide two implementations of foo(). And calling either of them will be really awkward, requiring multiple casts to disambiguate. This usually is not what you want.
To resolve this, use virtual inheritance:
struct interface_base
{
virtual void foo() = 0;
};
struct interface : virtual public interface_base
{
virtual void bar() = 0;
};
struct implementation_base : virtual public interface_base
{
void foo();
};
struct implementation : public implementation_base, virtual public interface
{
void bar();
};
int main()
{
implementation x;
}
With virtual inheritance, only one instance of the base class in question is created in the inheritance heirarchy for all virtual mentions. Thus, there's only one foo(), which can be satisfied by implementation_base::foo().
For more information, see this prior question - the answers provide some nice diagrams to make this all more clear.
The usual C++ idiom is:
public virtual inheritance for interface classes
private non-virtual inheritance for implementation classes
In this case we would have:
struct interface_base
{
virtual void foo() = 0;
};
struct interface : virtual public interface_base
{
virtual void bar() = 0;
};
struct implementation_base : virtual public interface_base
{
void foo();
};
struct implementation : private implementation_base,
virtual public interface
{
void bar();
};
In implementation, the unique interface_base virtual base is :
publicly inherited via interface: implementation --public--> interface --public--> interface_base
privately inherited via implementation_base: implementation --private--> implementation_base --public--> interface_base
When client code does one of these derived to base conversions:
derived to base pointer conversions,
reference binding of base type with an initializer of static type derived,
access to inherited base class members via a lvalue of derived static type,
what matters is only that there is a least one accessible inheritance path from the derived class to the given base class subobject; other inaccessible paths are simply ignored. Because inheritance of the base class is only virtual here, there is only one base class subject so these conversions are never ambiguous.
Here, the conversion from implementation to interface_base, can always be done by client code via interface; the other inaccessible path does not matter at all. The unique interface_base virtual base is publicly inherited from implementation.
In many cases, the implementation classes (implementation, implementation_base) will be kept hidden from client code: only pointers or references to the interface classes (interface, interface_base) will be exposed.
For the case of 'solving' the diamond inheritance problem, the solutions offered by bdonlan are valid. Having said that, you can avoid the diamond-problem with design. Why must every instance of a given class be seen as both classes? Are you ever going to pass this same object to a class that says something like:
void ConsumeFood(Food *food);
void ConsumeDrink(Drink *drink);
class NutritionalConsumable {
float calories() = 0;
float GetNutritionalValue(NUTRITION_ID nutrition) = 0;
};
class Drink : public NutritionalConsumable {
void Sip() = 0;
};
class Food : public NutritionalConsumable {
void Chew() = 0;
};
class Icecream : public Drink, virtual public Food {};
void ConsumeNutrition(NutritionalConsumable *consumable) {
ConsumeFood(dynamic_cast<Food*>(food));
ConsumeDrink(dynamic_cast<Drink*>(drink));
}
// Or moreso
void ConsumeIcecream(Icecream *icecream) {
ConsumeDrink(icecream);
ConsumeFood(icecream);
}
Surely it would be better in this case for Icecream to just implement NutritionalConsumable and provide a GetAsDrink() and GetAsFood() method that will return a proxy, purely for the sake of appearing as either food or drink. Otherwise that suggests that there is a method or object that accepts a Food but somehow wants to later see it as a Drink, which can only be achieved with a dynamic_cast, and needn't be the case with a more appropriate design.
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...
}
};
I have an abstract class CommandPath, and a number of derived classes as below:
class CommandPath {
public:
virtual CommandResponse handleCommand(std::string) = 0;
virtual CommandResponse execute() = 0;
virtual ~CommandPath() {}
};
class GetTimeCommandPath : public CommandPath {
int stage;
public:
GetTimeCommandPath() : stage(0) {}
CommandResponse handleCommand(std::string);
CommandResponse execute();
};
All of the derived classes have the member variable 'stage'. I want to build a function into all of them which manipulates 'stage' in the same way, so rather than defining it many times I thought I'd build it into the parent class. I moved 'stage' from the private sections of all of the derived classes into the protected section of CommandPath, and added the function as follows:
class CommandPath {
protected:
int stage;
public:
virtual CommandResponse handleCommand(std::string) = 0;
virtual CommandResponse execute() = 0;
std::string confirmCommand(std::string, int, int, std::string, std::string);
virtual ~CommandPath() {}
};
class GetTimeCommandPath : public CommandPath {
public:
GetTimeCommandPath() : stage(0) {}
CommandResponse handleCommand(std::string);
CommandResponse execute();
};
Now my compiler tells me for the constructor lines that none of the derived classes have a member 'stage'. I was under the impression that protected members are visible to derived classes?
The constructor is the same in all classes, so I suppose I could move it to the parent class, but I'm more concerned about finding out why the derived classes aren't able to access the variable.
Also, since previously I've only used the parent class for pure virtual functions, I wanted to confirm that this is the way to go about adding a function to be inherited by all derived classes.
Try this:
class CommandPath {
protected:
int stage;
public:
CommandPath(int stage_) : stage(stage_) {}
};
class GetTimeCommandPath : public CommandPath {
public:
GetTimeCommandPath(int stage_) : CommandPath(stage_) {}
};
(Omitted extra code for brevity).
You can't use the initializer list on a parent class' members, only the current one's. If that makes sense.
First of all: don't use protected for attributes.
It may seem arbitrary, but the point is that it breaks encapsulation. Imagine that suddenly you realize what of space it is to use an int when an unsigned short would have done, so you go ahead and change CommandPath.
Unfortunately, since all the classes deriving from CommandPath could access stage directly, there is a strong change the compiler will complain now: void changeStage(int&); is no longer suitable for example, so you have to reword it... and it's messy.
Proper encapsulation requires that you don't expose your attributes: they are defined as private and you never return handles to them. The idiomatic way is to provide Get and Set methods (you don't necessarily have to change their type, or you may provide overloads, etc...)
Also protected is quite a bastard keyword, it does not protect much and the accessibility restriction it is supposed to define is weak:
class Base { protected: void specialMethod(); };
struct Derived: Base { void specialForward() { specialMethod(); } };
A simple case of deriving and it's now public, that's why it can't be used for encapsulation ;)
In C++ an interface can be implemented by a class whose methods are pure virtual.
Such a class could be part of a library to describe what methods an object should implement to be able to work with other classes in the library:
class Lib::IFoo
{
public:
virtual void method() = 0;
};
:
class Lib::Bar
{
public:
void stuff( Lib::IFoo & );
};
Now I want to to use class Lib::Bar, so I have to implement the IFoo interface.
For my purposes I need a whole of related classes so I would like to work with a base class that guarantees common behavior using the NVI idiom:
class FooBase : public IFoo // implement interface IFoo
{
public:
void method(); // calls methodImpl;
private:
virtual void methodImpl();
};
The non-virtual interface (NVI) idiom ought to deny derived classes the possibility of overriding the common behavior implemented in FooBase::method(), but since IFoo made it virtual it seems that all derived classes have the opportunity to override the FooBase::method().
If I want to use the NVI idiom, what are my options other than the pImpl idiom already suggested (thanks space-c0wb0y).
I think you've got your NVI pattern around the wrong way:
http://en.wikibooks.org/wiki/More_C%2B%2B_Idioms/Non-Virtual_Interface
Not sure if that solves your issue though.
class IFoo
{
public:
void method() { methodImpl(); }
private:
virtual void methodImpl()=0;
};
class FooBase : public IFoo // implement interface IFoo
{
private:
virtual void methodImpl();
};
Here's an example of why you might do this using a reader that reads from XML and another from DB. Note that common structure is moved into the NVI readFromSource, while non-common behaviour is moved into the private virtual getRawDatum. This way logging and error checking is only needed in the one function.
class IReader
{
public:
// NVI
Datum readFromSource()
{
Datum datum = getRawDatum();
if( ! datum.isValid() ) throw ReaderError("Unable to get valid datum");
logger::log("Datum Read");
return datum;
}
private:
// Virtual Bits
Datum getRawDatum()=0;
};
class DBReader : public IReader
{
private:
Datum getRawDatum() { ... }
};
class XmlReader : public IReader
{
private:
Datum getRawDatum() { ... }
};
Commonly, the reason for using the NVI (sometimes also called "Template Method") is that derived classes should only change a part of the base class' behavior. So what you do is this:
class base {
public:
void f()
{
// do something derived classes shouldn't interfere with
vf();
// do something derived classes shouldn't interfere with
vg();
// do something derived classes shouldn't interfere with
vh();
// do something derived classes shouldn't interfere with
}
private:
virtual void vf(); // might be pure virtual, too
virtual void vg(); // might be pure virtual, too
virtual void vh(); // might be pure virtual, too
};
Derived classes can then plug into f() at the spots they are meant to and change aspects of f()'s behavior, without messing up its fundamental algorithm.
It may be confusing that once a method is declared as virtual in a base class, it automatically becomes virtual in all derived classes, even if the virtual keywords is not used there. So in your example, both methods of FooBase are virtual.
... to deny derived classes the
possibility of overriding the common
behavior implemented in
FooBase::method()...
If you can get rid of IFoo, and just start the hierarchy with FooBase with a non-virtual method, that would do it. But it looks like you want to allow direct children of IFoo to override method(), but to prevent children of FooBase to override it. I don't think that's possible.
You could use the pimpl-idiom to achieve this:
class IFoo
{
public:
IFoo( boost::shared_ptr< IFooImpl > pImpl )
: m_pImpl( pImpl )
{}
void method() { m_pImpl->method(); }
void otherMethod() { m_pImpl->otherMethod(); }
private:
boost::shared_ptr< IFooImpl > m_pImpl;
};
class IFooImpl
{
public:
void method();
virtual void otherMethod();
};
Now others can still subclass IFooImpl and pass it to IFoo, but they cannot override the behavior of method (they can override otherMethod). You can even make IFooImpl a direct subclass of IFoo and use enable_shared_from_this to initialize IFoo correctly. This is just the gist of the method. There are many ways to tweak this approach. For instance you can use the factory-pattern to make sure IFoos are created correctly.
Hope that helps.