Edit Made clear() and append() public in "ProductionNode"
I am trying to implement in C++ a similar example to the one presented at "Working effectively with Legacy code" page 359, the resulting diagram class at page 361.
It uses multiple inheritance; there is a base class "ProductionNode" which fully implements an interface called "Node", a second base class called "ProductionModelNode" which inherits from "ProductionNode" and from another interface called "ModelNode" which in turns inherits from the"Node" interface.
When I try to instantiate "ProductionModelNode" compiler claims that the methods defined at "Node" are not implemented, however they are implemented at "ProductionNode".
#include<algorithm>
#include <string>
class Node
{
public:
virtual void clear() = 0;
virtual void append(const std::string&) = 0;
};
class ProductionNode : public Node
{
public:
virtual void clear() override
{
m_name.clear();
}
virtual void append(const std::string& suffix) override
{
m_name += suffix;
}
protected:
std::string m_name;
};
class ModelNode : public Node
{
public:
virtual void reverse() = 0;
virtual void uppercase() = 0;
};
class ProductionModelNode : public ModelNode, public ProductionNode
{
public:
virtual void reverse() override
{
std::reverse(std::begin(m_name), std::end(m_name));
}
virtual void uppercase() override
{
std::transform(m_name.begin(), m_name.end(), m_name.begin(), ::toupper);
}
private:
int m_age;
};
int main(int argc, char** argv)
{
ProductionModelNode mn;
return 0;
}
This is a case of Dreadful Diamond on Derivation.
The class ProductionModelNode has two Node parent, one from ProductionNode is implemented, but the other from ModelNode is not.
Possible "trial" solutions:
Remove the inheritance from ModelNode
Implement clear and append in ProductionModelNode
Use virtual inheritance
Example using virtual inheritance:
class ProductionNode : virtual public Node
...
class ModelNode: virtual public Node
When you define a method with = 0 sign (for example: virtual void reverse() = 0;) it means that the method defined to be Pure virtual.
You must implement every "Pure virtual" method in every class that derive from the class that contains the "pure virtual" methods. (in your case Node class).
class ProductionModelNode : public ModelNode, public ProductionNode
{
public:
...
virtual void clear() override {
//implementation
}
virtual void append(const std::string&) override {
//implementation
}
...
}
Related
I get error when i try to compile this code.
class FunctionVisitor
{
public:
virtual ~FunctionVisitor() = default;
virtual void visit(SumTimer&) = 0;
virtual void visit(SumSelector&) = 0;
};
class timerVisitor : public FunctionVisitor
{
private:
std::string variableName;
std::string variableValue;
public:
timerVisitor(std::string varName, std::string varValue) : variableName(varName), variableValue(varValue) { }
virtual void visit(SumTimer& fun) override;
};
class selectorVisitor : public FunctionVisitor
{
private:
std::string variableName;
std::string variableValue;
public:
selectorVisitor(std::string varName, std::string varValue) : variableName(varName), variableValue(varValue) { }
virtual void visit(SumSelector& sel) override;
};
The reason is that i have pure virtual functions in the base class but each sub class only has defination of one function of the base class virtual function.
Can i have pure virtual functions in this case ?
Every class that inherits from abstract class in c++ and doesn't override all of its pure virtual functions is considered abstract and cannot be instantiated neither locally nor dynamically. You can either override the functions to do nothing (or return an exception)
virtual void visit(SumTimer& fun) override {}
or make the abstract class concrete and the functions do nothing by default
class FunctionVisitor
{
public:
virtual ~FunctionVisitor() = default;
virtual void visit(SumTimer&) {}
virtual void visit(SumSelector&) {}
};
What do you want to happen if you call a different function? E.g. if you call visit(SumSelector&) on a timerVisitor?
#user253751 i don't want any action in that case.
If you don't want anything to happen when the function is called but not overridden, then make the base class have a function that does nothing. Instead of
virtual void visit(SumTimer&) = 0;
write:
virtual void visit(SumTimer&) {}
Pure virtual (= 0) means that you want to force derived classes to override the function. If you don't want to do that, then don't make them pure virtual!
I'm asked to implement an interface and I'm wondering what would be the best strategy to factorize the code as much as possible.
Here is the interface definition (I'm not supposed to change it):
#include <string>
class BaseIf
{
public:
virtual ~BaseIf() {}
virtual std::string getName() = 0;
};
class IntIf : public BaseIf
{
public:
virtual ~IntIf() {}
virtual int getValue() = 0;
};
class FloatIf : public BaseIf
{
public:
virtual ~FloatIf() {}
virtual float getValue() = 0;
};
I'll end up with IntImpl (implementing IntIf) and FloatImpl (implementing FloatIf). But I'm wondering where I should put any code common to those two classes (like the name attribute management or any other stuff required by BaseIf which is actually much bigger than in this MCVE).
If I create BaseImpl (implementing BaseIf's getName function) with the common code, and have IntImpl derive from it (and IntIf), then I need to also implement getName in it because it's reported as not implemented. And I also get double inheritance of BaseIf...
I was wondering if Pimpl pattern would help, then IntImpl would have a BaseImpl object as attribute (and only derive from IntIf), but then, again, I need to implement getName in IntImpl to "forward" the call to the BaseImpl attribute. So as BaseIf has actually many virtual functions this is just going to be a real pain to maintain.
Is there no smart solution/pattern making it possible to implement once only getName in a common place? Or is it just the interface that is bad and should be reworked?
This is the primary use case for virtual inheritance.
Despite all the stigma that surrionds multiple and virtual inheritance, there are no particular problems when oure interfaces (no data members) are virtually inherited. Here's the gist:
class BaseIf
{
public:
virtual ~BaseIf() {}
virtual std::string getName() = 0;
};
class IntIf : public virtual BaseIf
{
public:
virtual ~IntIf() {}
virtual int getValue() = 0;
};
class BaseImpl : public virtual BaseIf
{
public:
std::string getName () override { return "whoa dude"; }
};
class IntImpl : public virtual IntIf, public BaseImpl
{
public:
int getValue() override { return 42; }
};
full demo
With a deeper hierarchy one probably would have to virtually inherit implementation classes as well, which is not very convenient but still doable.
An alternative to virtual inheritance of implementation would be to stratify the implementation into a "building blocks" layer and the final layer. Building blocks are standalone and do not inherit other building blocks. (They may inherit interfaces). The final classes inherit building blocks but not other final classes.
class BaseBlock : public virtual BaseIf
{
public:
std::string getName () override { return "whoa dude"; }
};
class IntBlock : public virtual IntIf
{
public:
int getValue() override { return 42; }
};
class BaseImpl : public BaseBlock {};
class IntImpl : public BaseBlock, public IntBlock {};
full demo
One does need to made changes to the interfaces if there was no virtual inheritance in the hierarchy. These changes are however transparent (the clients code need not be changed, only recompiled) and probably beneficial anyway.
Without virtual inheritance, one would have to resort to lots of boilerplate.
class BaseBlock // no base class!
{
public:
virtual std::string getName () { return "whoa dude"; }
};
class BaseImpl : public BaseIf, public BaseBlock
{
public:
// oops, getName would be ambiguous here, need boplerplate
std::string getName () override { return BaseBlock::getName(); }
};
You can make a template class that implements the common part of an interface like this:
template <class IFACE> class BaseImpl : public IFACE
{
public:
std::string getName () override { ... }
}
and then
class IntImpl : public BaseImpl<IntIf>
{
public:
int getValue() override { ... }
}
The result is a simple single-inheritance chain. BaseIf <- IntIf <- BaseImpl <- IntImpl
Make sure you have a good reason for IntIf and FloatIf to exist, though -- in your MCVE they look like they don't need to be there at all.
You can provide default implementation for pure virtual functions:
struct A {
virtual void frob() = 0;
};
void A::frob() {
std::cout << "default";
}
struct B : A {
void frob() override {
A::frob(); // calls the default
}
};
If I'm reading your problem correctly, you'd like a default implementation for getName(). So solve that, simply provide an implementation and call it:
class IntIf : public BaseIf
{
public:
virtual ~IntIf() {}
virtual int getValue() = 0;
std::string getName() override {
return BaseIf::getName();
}
};
class FloatIf : public BaseIf
{
public:
virtual ~FloatIf() {}
virtual float getValue() = 0;
std::string getName() override {
return BaseIf::getName();
}
};
I have the following Base Class.
class Furniture
{
public:
virtual void Collapse() = 0;
};
With derived classes:
class Table : public Furniture
{
public:
void Collapse()
{
Save(my_file);
}
protected:
void Save(char* filepath);
private:
char* my_file;
};
class Armoire : public Furniture
{
public:
void Collapse()
{
Save(my_file);
}
protected:
void Save(char* filepath);
private:
char* my_file;
};
class Chair : public Furniture
{
public:
void Collapse()
{
Save(); // note - no filepath
}
protected:
void Save();
};
After reading the comments, I have edited this question somewhat, to describe more accurately the problem in hand.
My problem is that all but one of the classes derived from Furniture define the Save() function with a parameter, like Table and Armoire are doing. It's only the Chair class that defines a Save() function with no parameter.
I want to somehow move the declaration of the Save() function - to be part of an interface, and have the derived classes provide the implementation. But that one class Chair that does not require a parameter means that I can't do this.
What is the best way to design this?
Use a default parameter in the base class:
virtual void Collapse( int seconds = 0 ) = 0;
Please refer the following example.
using namespace std;
//Base interface
class IBase
{
public:
virtual void BaseMethod1() = 0;
virtual void BaseMethod2() = 0;
};
class IEntity1 : public IBase
{
public:
virtual void Entity1Method1() = 0;
virtual void Entity1Method2() = 0;
};
class Entity1 : public IEntity1
{
public:
Entity();
//IBaseMethods
void BaseMethod1();
void BaseMethod2();
//IEntityMethods
void Entity1Method1();
void Entity1Method2();
//EntityMethods
void Method1();
void Method2();
};
In the above example, for all other entities deriving from IBase needs to implement BaseMethod1() and BaseMethod2().Because of which lots of code duplication is happening? Is there anyway where we can avoid redundant implementation of IBase methods in entities deriving from it?
You can use virtual inheritance in combination with a default base implementation class to encapsulate your default base behavior, and have it be only inherited by the concrete classes you want, like follows:
using namespace std;
//Base interface
class IBase
{
public:
virtual void BaseMethod1() = 0;
virtual void BaseMethod2() = 0;
};
class IEntity1 : virtual public IBase
{
public:
virtual void Entity1Method1() = 0;
virtual void Entity1Method2() = 0;
};
class BaseImpl : virtual public IBase
{
public:
virtual void BaseMethod1()
{
...
}
virtual void BaseMethod2()
{
...
}
}
class Entity1 : public IEntity1, public BaseImpl
{
public:
Entity1();
//IEntityMethods
void Entity1Method1();
void Entity1Method2();
//EntityMethods
void Method1();
void Method2();
};
There is, however, a runtime cost associated with virtual inheritance. Multiple inheritance also comes with some structural issues, e.g. base class construction.
You can even have some fun with template classes to make your class composition more modular:
template<typename TEntity, typename TBaseImpl>
class ConcreteEntity: public TEntity, public TBaseImpl
{
public:
ConcreteEntity() {}
};
class ConreteEntity1 : public ConcreteEntity<IEntity1, BaseImpl>
{
public:
ConreteEntity1();
//IEntityMethods
void Entity1Method1();
void Entity1Method2();
//ConreteEntity1 Methods
void Method1();
void Method2();
};
You could make a function that is called in BaseMethod1() implementations that are the same.
Something like this:
void BaseMethod1_common();
class Entity1 : public IEntity1
{
public:
Entity();
//IBaseMethods
void BaseMethod1() { BaseMethod1_common(); }
void BaseMethod2();
//IEntityMethods
void Entity1Method1();
void Entity1Method2();
//EntityMethods
void Method1();
void Method2();
};
First of all IBase deserves a virtual destructor.
Declare it pure virtual and define IBase:BaseMethod1() and
IBase::BaseMethod1().
If your intention is to hide implementation, then the only option would be to release the code as a library and then share only the header file among the other developers.
Implementing a global function, or using multiple inheritance as suggested still mean that your implementation is exposed.
However, if the intent is to reduce coupling among the various classes, there's another option :
Create a class that has the actual shared implementation, and then another class which will be an interface to it.
This interface class will then be the base class for other derived entities.
Example code is shown below :
//First Header and Cpp file
class Base_private
{
public:
BaseImpl(arguments);
~BaseImpl();
void BaseMethod1() {
//Implementation
}
void BaseMethod2() {
//Implementation
}
};
//Second Header and Cpp file
class BaseInterface
{
public:
BaseInterface(arguments);
~BaseInterface();
void BaseMethod1() {
m_pBase->BaseMethod1();
}
void BaseMethod2() {
m_pBase->BaseMethod2();
}
private:
Base_private* m_pBase;
};
class Entity : public BaseInterface
{
public:
Entity(arguments);
~Entity();
void Method1();
void Method2();
};
There are two base classes have same function name. I want to inherit both of them, and over ride each method differently. How can I do that with separate declaration and definition (instead of defining in the class definition)?
#include <cstdio>
class Interface1{
public:
virtual void Name() = 0;
};
class Interface2
{
public:
virtual void Name() = 0;
};
class RealClass: public Interface1, public Interface2
{
public:
virtual void Interface1::Name()
{
printf("Interface1 OK?\n");
}
virtual void Interface2::Name()
{
printf("Interface2 OK?\n");
}
};
int main()
{
Interface1 *p = new RealClass();
p->Name();
Interface2 *q = reinterpret_cast<RealClass*>(p);
q->Name();
}
I failed to move the definition out in VC8. I found the Microsoft Specific Keyword __interface can do this job successfully, code below:
#include <cstdio>
__interface Interface1{
virtual void Name() = 0;
};
__interface Interface2
{
virtual void Name() = 0;
};
class RealClass: public Interface1,
public Interface2
{
public:
virtual void Interface1::Name();
virtual void Interface2::Name();
};
void RealClass::Interface1::Name()
{
printf("Interface1 OK?\n");
}
void RealClass::Interface2::Name()
{
printf("Interface2 OK?\n");
}
int main()
{
Interface1 *p = new RealClass();
p->Name();
Interface2 *q = reinterpret_cast<RealClass*>(p);
q->Name();
}
but is there another way to do this something more general that will work in other compilers?
This problem doesn't come up very often. The solution I'm familiar with was designed by Doug McIlroy and appears in Bjarne Stroustrup's books (presented in both Design & Evolution of C++ section 12.8 and The C++ Programming Language section 25.6). According to the discussion in Design & Evolution, there was a proposal to handle this specific case elegantly, but it was rejected because "such name clashes were unlikely to become common enough to warrant a separate language feature," and "not likely to become everyday work for novices."
Not only do you need to call Name() through pointers to base classes, you need a way to say which Name() you want when operating on the derived class. The solution adds some indirection:
class Interface1{
public:
virtual void Name() = 0;
};
class Interface2{
public:
virtual void Name() = 0;
};
class Interface1_helper : public Interface1{
public:
virtual void I1_Name() = 0;
void Name() override
{
I1_Name();
}
};
class Interface2_helper : public Interface2{
public:
virtual void I2_Name() = 0;
void Name() override
{
I2_Name();
}
};
class RealClass: public Interface1_helper, public Interface2_helper{
public:
void I1_Name() override
{
printf("Interface1 OK?\n");
}
void I2_Name() override
{
printf("Interface2 OK?\n");
}
};
int main()
{
RealClass rc;
Interface1* i1 = &rc;
Interface2* i2 = &rc;
i1->Name();
i2->Name();
rc.I1_Name();
rc.I2_Name();
}
Not pretty, but the decision was it's not needed often.
You cannot override them separately, you must override both at once:
struct Interface1 {
virtual void Name() = 0;
};
struct Interface2 {
virtual void Name() = 0;
};
struct RealClass : Interface1, Interface2 {
virtual void Name();
};
// and move it out of the class definition just like any other method:
void RealClass::Name() {
printf("Interface1 OK?\n");
printf("Interface2 OK?\n");
}
You can simulate individual overriding with intermediate base classes:
struct RealClass1 : Interface1 {
virtual void Name() {
printf("Interface1 OK?\n");
}
};
struct RealClass2 : Interface2 {
virtual void Name() {
printf("Interface2 OK?\n");
}
};
struct RealClass : RealClass1, RealClass2 {
virtual void Name() {
// you must still decide what to do here, which is likely calling both:
RealClass1::Name();
RealClass2::Name();
// or doing something else entirely
// but note: this is the function which will be called in all cases
// of *virtual dispatch* (for instances of this class), as it is the
// final overrider, the above separate definition is merely
// code-organization convenience
}
};
Additionally, you're using reinterpret_cast incorrectly, you should have:
int main() {
RealClass rc; // no need for dynamic allocation in this example
Interface1& one = rc;
one.Name();
Interface2& two = dynamic_cast<Interface2&>(one);
two.Name();
return 0;
}
And here's a rewrite with CRTP that might be what you want (or not):
template<class Derived>
struct RealClass1 : Interface1 {
#define self (*static_cast<Derived*>(this))
virtual void Name() {
printf("Interface1 for %s\n", self.name.c_str());
}
#undef self
};
template<class Derived>
struct RealClass2 : Interface2 {
#define self (*static_cast<Derived*>(this))
virtual void Name() {
printf("Interface2 for %s\n", self.name.c_str());
}
#undef self
};
struct RealClass : RealClass1<RealClass>, RealClass2<RealClass> {
std::string name;
RealClass() : name("real code would have members you need to access") {}
};
But note that here you cannot call Name on a RealClass now (with virtual dispatch, e.g. rc.Name()), you must first select a base. The self macro is an easy way to clean up CRTP casts (usually member access is much more common in the CRTP base), but it can be improved. There's a brief discussion of virtual dispatch in one of my other answers, but surely a better one around if someone has a link.
I've had to do something like this in the past, though in my case I needed to inherit from one interface twice and be able to differentiate between calls made on each of them, I used a template shim to help me...
Something like this:
template<class id>
class InterfaceHelper : public MyInterface
{
public :
virtual void Name()
{
Name(id);
}
virtual void Name(
const size_t id) = 0;
}
You then derive from InterfaceHelper twice rather than from MyInterface twice and you specify a different id for each base class. You can then hand out two interfaces independently by casting to the correct InterfaceHelper.
You could do something slightly more complex;
class InterfaceHelperBase
{
public :
virtual void Name(
const size_t id) = 0;
}
class InterfaceHelper1 : public MyInterface, protected InterfaceHelperBase
{
public :
using InterfaceHelperBase::Name;
virtual void Name()
{
Name(1);
}
}
class InterfaceHelper2 : public MyInterface, protected InterfaceHelperBase
{
public :
using InterfaceHelperBase::Name;
virtual void Name()
{
Name(2);
}
}
class MyClass : public InterfaceHelper1, public InterfaceHelper2
{
public :
virtual void Name(
const size_t id)
{
if (id == 1)
{
printf("Interface 1 OK?");
}
else if (id == 2)
{
printf("Interface 2 OK?");
}
}
}
Note that the above hasn't seen a compiler...
class BaseX
{
public:
virtual void fun()
{
cout << "BaseX::fun\n";
}
};
class BaseY
{
public:
virtual void fun()
{
cout << "BaseY::fun\n";
}
};
class DerivedX : protected BaseX
{
public:
virtual void funX()
{
BaseX::fun();
}
};
class DerivedY : protected BaseY
{
public:
virtual void funY()
{
BaseY::fun();
}
};
class DerivedXY : public DerivedX, public DerivedY
{
};
There are two other related questions asking nearly (but not completely) identical things:
Picking from inherited shared method names. If you want to have rc.name() call ic1->name() or ic2->name().
Overriding shared method names from (templated) base classes. This has simpler syntax and less code that your accepted solution, but does not allow for access to the functions from the derived class. More or less, unless you need to be able to call name_i1() from an rc, you don't need to use things like InterfaceHelper.