I'm looking for a clean way of doing this since a long time. In my problem, there exist 3 classes not sharing any parent in common but each having some methods with the same name (A.doSomething, B.doSomething, C.doSomething). Hence, having the same function signature, class D inheriting from A and using method doSomething() will "look the same" to E inheriting from B or C .
Here is a sketch of what I'd like to be able to do:
class Base {
public:
void myMethod(void) { doSomething(); }
};
class Independent {
public:
doSomething();
};
clase Derived : public Base : public Independent {
(...)
};
int main(void) {
Derived *derivedObject = new Derived();
derivedObject->myMethod();
}
In this problem, object of type "Independent" is provided by a library that I cannot change. I would like to define a base class that uses methods that are going to be inherited later on. I couldn't find a proper way of doing this using virtual inheritance without causing ambiguous compiling.
You've got a nasty situation there. One solution to this would be using the Curiously Recurring Template Pattern to perform the inheritance at compile-time, like this:
template <typename D>
class Base {
public:
void myMethod(void) { static_cast<D*>(this)->doSomething(); }
};
class Independent {
public:
void doSomething();
};
clase Derived : public Base : public Independent {
/*...*/
};
int main(void) {
Derived *derivedObject = new Derived();
derivedObject->myMethod();
}
Alternatively, you could choose to put a middleman class in between to forward to Independent (I assume you have many classes deriving from the same Base and Independent, and just don't want to have to do this for each class).
template <typename D>
class Base {
private:
virtual void doSomethingImpl();
public:
void myMethod(void) { doSomethingImpl(); }
};
class Independent {
public:
void doSomething();
};
class IndependentWrapper : public Base : public Independent {
private:
void doSomethingImpl() { Independent::doSomething(); }
};
clase Derived : public IndependentWrapper {
/*...*/
};
int main(void) {
Derived *derivedObject = new Derived();
derivedObject->myMethod();
}
Related
My starting situation where I don't know what type to use in Base class:
class Base {
private:
virtual void doSomethingSpecific(?type param) = 0;
public:
// this function uses doSomethingSpecific
void doSomething() {...}
};
class Derived1 : public Base {
private:
void doSomethingSpecific(Derived1Type param) override;
};
class Derived2 : public Base {
private:
void doSomethingSpecific(Derived2Type param) override;
};
My solution using templates:
template<typename DerivedType>
class Base {
private:
virtual void doSomethingSpecific(DerivedType param) = 0;
public:
// this function uses doSomethingSpecific
void doSomething() {...}
};
class Derived1 : public Base<Derived1Type> {
private:
void doSomethingSpecific(Derived1Type param) override;
};
class Derived2 : public Base<Derived2Type> {
private:
void doSomethingSpecific(Derived2Type param) override;
};
This works, but I am posting this because it feels like this my not be the most optimal/straightforward approach? Also even though the header files are simple, templates significantly increased compile time.
Here is a more specific example of how I use doSomethingSpecific function:
template<typename DerivedType>
class Base {
std::vector<DerivedType> components;
private:
virtual void doSomethingSpecific(DerivedType param) = 0;
public:
Base(std::vector<DerivedType> components) {
this->components = components;
}
// this function uses doSomethingSpecific
void doSomething() {
doSomethingSpecific(components[0]);
}
};
class Derived1 : public Base<Derived1Type> {
private:
void doSomethingSpecific(Derived1Type param) override;
};
int main() {
std::vector<Derived1Type> components = {...};
Derived1 obj(components);
obj.doSomething();
}
I do not understand the first example of your code. It is not clear why there is public inheritance and a virtual method. In the second example it is apparent there there is no need for the virtual method. Base<A> and Base<B> are two unrelated types. Consequently Derived1 and Derived2 do not share a common base. There is no runtime polymorphism.
For compile time polymorphism you can employ the CRTP (curiously recurring template pattern). Your code looks already very similar. The major change I had to make is to remove the overriding (its not needed):
#include <iostream>
template<typename T>
struct Base {
void doSomething() {
static_cast<T*>(this)->doSomethingSpecific(typename T::type{});
}
};
struct Derived1 : public Base<Derived1> {
using type = int;
void doSomethingSpecific(type param) { std::cout << "hello int " << param; }
};
struct Derived2 : public Base<Derived2> {
using type = double;
void doSomethingSpecific(type param) { std::cout << "hello double " << param; }
};
int main() {
Derived1{}.doSomething();
Derived2{}.doSomething();
}
Live Demo
I also added a member alias type that Base can use to construct the parameter to pass to the methods. And for CRTP to work the base must be parametrized on the deriving class.
Again: Derived1 and Derived2 do not share a common base (as was the case already in your code).
Context: I'm doing some internal cleanup to move away from large & unwieldy data structures to more well-defined data structures.
Current
I have a class that does something like this:
class Base {
public:
virtual int DoStuff(BigType input);
};
Calling code:
std::vector<Base*> bases;
BigType input;
for (const auto& base : bases) {
base.DoStuff(input);
}
Child classes currently look like this:
class Child : public Base {
int DoStuff(BigType input) const override {
// do stuff
}
};
Attempted
I added an intermediate interface:
template <typename SmallType>
class FocusedBase : public Base {
public:
int DoStuff(BigType input) const override {
return DoStuff(SmallType(input));
}
virtual int DoStuff(SmallType input);
};
Child classes now look like this. Note that SmallType may differ across child classes:
class Child : public FocusedBase<SmallType> {
int DoStuff(SmallType input) {
// do stuff
}
};
Calling code remains the same.
Issue
I'd like to have new classes inherit from FocusedBase only, not Base. Any thoughts on how to do so?
If you want to disallow inheriting from Base directly you can make Base::Base() private and make FocusedBase a friend:
struct Base {
private:
Base() = default;
friend class FocusedBase;
};
struct FocusedBase : Base {};
struct Foo : Base {};
struct Bar : FocusedBase {};
int main() {
//Foo f; // error
Bar b; // ok
}
I'm currently trying to wrap my head around the basics of C++ inheritance. Consider the following piece of code:
// Interfaces
class InterfaceBase
{
public:
virtual void SomeMethod() = 0;
};
class InterfaceInherited : public InterfaceBase
{
};
// Classes
class ClassBase : public InterfaceBase
{
public:
virtual void SomeMethod()
{
}
};
class ClassInherited : public ClassBase, public InterfaceInherited
{
};
int main()
{
ClassBase myBase; // OK
ClassInherited myInherited; // Error on this line
return 0;
}
Here I have two interfaces with an inheritance relationship. The same goes for the two classes which implement the interfaces.
This gives me the following compiler error:
C2259 'ClassInherited': cannot instantiate abstract class
It seems that the class ClassInherited does not inherit the implementation of SomeMethod from ClassBase. Thus it is abstract and cannot be instantiated.
How would I need to modify this simple example in order to let ClassInherited inherit all the implemented methods from ClassBase?
You are encountering a diamond problem.
The solution is to use virtual inheritance (Live), to ensure that only one copy of base class members are inherited by grand-childs:
// Interfaces
class InterfaceBase
{
public:
virtual void SomeMethod() = 0;
};
class InterfaceInherited : virtual public InterfaceBase
{
};
// Classes
class ClassBase : virtual public InterfaceBase
{
public:
virtual void SomeMethod()
{
}
};
class ClassInherited : public ClassBase, public InterfaceInherited
{
};
int main()
{
ClassBase myBase; // OK
ClassInherited myInherited; // OK
return 0;
}
Let a class hierarchy :
class Base { virtual ~Base() throw(); };
class DerivedA : public Base { };
class DerivedB : public Base { };
I would like to have some code specific to each of these derived classes. However that code also being specific to the application that makes use of this class hierarchy, I do not want to embbed this derived-class-specific code into these derived classes. To avoid doing so, I thought about writing free functions :
void DerivedASpecificWork( DerivedA da );
void DerivedBSpecificWork( DerivedB db );
However, when given an instance of a derived class through a reference/pointer to a Base, I do not have access to the actual type of the instance, and thus cannot call the proper Derived*SpecificWork() function.
I would like to know if there is nome kind of design pattern that would allow me to call a derived-class-specific function without knowing the actual type of the instance, i.e having the same mechanism as virtual functions provide, but without having these virtual functions that would require me to embbed application-specific code into that class hierarchy.
Actually, why I want to do that is to provide informations about an exception that occured within a natively implemented function called by a Lua script. Each exception carrying its own set of information, the way I want to represent the error within the script depends on the type of the exception. I could create a pure virtual method in the base class that would be implemented by derived classes, but this would require me to embbed Lua-related code into my exception hierarchy, which I do not want to do since the Lua is specific to one of the application using that exception hierarchy.
Also I cannot use C++11.
Thank you.
May be Brigde pattern can help you.
This pattern can be used when you want to avoid a permanent binding between an abstraction and it's implementation.
(I don't see your comment about your restriction in using c++11, but you can remove std::unique_ptr, std::move and override keyword)
class AppSpecificImp
{
public:
virtual void DoWork() = 0;
};
class Base
{
public:
virtual ~Base() throw();
virtual DoWork() = 0;
};
class DerivedA : public Base
{
public:
DerivedA(std::unique_ptr<AppSpecificImp> appImp)
: imp(std::move(appImp))
{
}
void DoWork() override
{
// DerivedA specific code
imp->DoWork();
}
private:
std::unique_ptr<AppSpecificImp> imp;
};
class DerivedB : public Base
{
public:
DerivedB(std::unique_ptr<AppSpecificImp> appImp)
: imp(std::move(appImp))
{
}
void DoWork() override
{
// DerivedB specific code
imp->DoWork();
}
private:
std::unique_ptr<AppSpecificImp> imp;
};
Edit to show Visitor pattern usage:
With visitor pattern you can do what you want but with more Effort.
class Visitor
{
public:
virtual void VisitDerivedA(DerivedA* object) = 0;
virtual void VisitDerivedB(DerivedB* object) = 0;
};
class Base
{
public:
virtual void Visit(Visitor* visitor) = 0;
};
class DerivedA : public Base
{
public:
virtual void Visit(Visitor* visitor)
{
visitor->VisitDerivedA(this);
}
};
class DerivedB : public Base
{
public:
virtual void Visit(Visitor* visitor)
{
visitor->VisitDerivedB(this);
}
};
class AppSpecificVisitor : public Visitor
{
public:
void VisitDerivedA(DerivedA* object)
{
// Do any work related to DerivedA class
}
void VisitDerivedB(DerivedB* object)
{
// Do any work related to DerivedB class
}
}
int main()
{
AppSpecificVisitor myVisitor;
Base* myBase = // any class in your hierarchy
myBase->Visit(&myVisitor);
}
As I said in comments with Visitor pattern you can add new functionally without changing the main hierarchy(Base->Derived types). You just define a new visitor implementation and write your logic for every class in main hierarchy. In your example you can pack app specific logic in an object and reference that in your derived objects that is an easier approach.
Why not using a new set of hierarchy for application specific implementation ?
class AppBase
{
public:
virtual ~AppBase() throw();
virtual void work_with_app() = 0;
};
class Base
{
public:
Base(AppBase& app) : m_app(app) {}
virtual ~Base() throw();
protected:
AppBase& m_app;
};
class DerivedA : public Base { DerivedA(AppBase& app) : Base(app) {} };
class DerivedB : public Base { DerivedA(AppBase& app) : Base(app) {} };
// Application specific implementation :
class AppLuaSpecific : public AppBase
{
public:
void work_with_app() { /* Lua app specific */ }
};
This way, your 1st hierarchy : Base, DerivedA, DerivedB can live without knowing anything about the app specific code implemented in AppLuaSpecific.
You can implement your own app-specific dispatch as follows (check it live on Coliru):
#include <iostream>
#include <typeinfo>
struct Base { virtual ~Base() {} };
struct DerivedA : public Base { };
struct DerivedB : public Base { };
namespace AppSpecific
{
template<class F>
void dispatch(const Base& b)
{
const std::type_info& t = typeid(b);
if ( t == typeid(DerivedA) )
F::doit(static_cast<const DerivedA&>(b));
else if ( t == typeid(DerivedB) )
F::doit(static_cast<const DerivedB&>(b));
}
struct Foo
{
static void doit(const DerivedA& da) { std::cout << "Foo(DerivedA)\n"; }
static void doit(const DerivedB& db) { std::cout << "Foo(DerivedB)\n"; }
};
struct Bar
{
static void doit(const DerivedA& da) { std::cout << "Bar(DerivedA)\n"; }
static void doit(const DerivedB& db) { std::cout << "Bar(DerivedB)\n"; }
};
} // namespace AppSpecific
int main()
{
DerivedA da;
DerivedB db;
Base& b1 = da;
Base& b2 = db;
AppSpecific::dispatch<AppSpecific::Foo>(b1);
AppSpecific::dispatch<AppSpecific::Foo>(b2);
AppSpecific::dispatch<AppSpecific::Bar>(b1);
AppSpecific::dispatch<AppSpecific::Bar>(b2);
}
I'd like to build a base (abstract) class (let's call it type::base) with some common funcionality and a fluent interface, the problem I'm facing is the return type of all those methods
class base {
public:
base();
virtual ~base();
base& with_foo();
base& with_bar();
protected:
// whatever...
};
Now I could make subtypes, e.g.:
class my_type : public base {
public:
myType();
// more methods...
};
The problem comes when using those subtypes like this:
my_type build_my_type()
{
return my_type().with_foo().with_bar();
}
This won't compile because we're returning base instead of my_type.
I know that I could just:
my_type build_my_type()
{
my_type ret;
ret.with_foo().with_bar();
return ret;
}
But I was thinking how can I implement it, and I've not found any valid ideas, some suggestion?
This problem of "losing the type" can be solved with templates - but it's rather complicated.
Eg.
class Pizza
{
string topping;
public:
virtual double price() const;
};
template <class T, class Base>
class FluentPizza : public Base
{
T* withAnchovies() { ... some implementation ... };
};
class RectPizza : public FluentPizza<RectPizza, Pizza>
{
double price() const { return length*width; :) }
};
class SquarePizza : public FluentPizza<SquarePizza, RectPizza>
{
... something else ...
};
You can then write
SquarePizza* p=(new SquarePizza)->withAnchovies();
The pattern is that instead of
class T : public B
you write
class T : public Fluent<T, B>
Another approach could be not to use fluent interface on the objects, but on pointers instead:
class Pizza { ... };
class RectPizza { ... };
class SquarePizza { ... whatever you might imagine ... };
template <class T>
class FluentPizzaPtr
{
T* pizza;
public:
FluentPizzaPtr withAnchovies() {
pizza->addAnchovies(); // a nonfluent method
return *this;
}
};
Use like this:
FluentPizzaPtr<SquarePizza> squarePizzaFactory() { ... }
FluentPizzaPtr<SquarePizza> myPizza=squarePizzaFactory().withAnchovies();
You should be returning references/pointers, and you should not need to keep the type information.
class base {
public:
base();
virtual ~base();
base &with_foo();
base &with_bar();
protected:
// whatever...
};
class my_type : public base {
public:
my_type();
// more methods...
};
base *build_my_type()
{
return &new my_type()->with_foo().with_bar();
}
You already have a virtual destructor. Presumably you have other virtual functions. Access everything through the base type and the virtual functions declared there.
One solution would work like this:
return *static_cast<my_type*>(&my_type().with_foo().with_bar());
Using static_cast basically tells the compiler 'I know what I'm doing here'.
In C++ you should be returing pointers or references rather than values. Also, you might want to explain what you mean by "fluent interfaces".
The way I'd do it in C#, and I believe it would work in C++ too is to provide a default implementation for with_foo() and with_bar()... Forgive my c#, but:
class base {
virtual base with_foo()
{ throw new NotImplementedException(); }
virtual base with_bar();
{ throw new NotImplementedException(); }
}