Refactoring inheritance into templates while retaining certain characteristics - c++

I have the following structure:
class Base {
virtual T foo() = 0;
};
class Derived : public Base {
T foo() override { /**/ }
}
class Derived1 : public Base {
T foo() override { /**/ }
}
I need the following to work (or an adequate substitute):
some_container<unique_ptr<Base>> objects;
Basically,
C++ AMP doesn't allow for virtual functions in kernels, but I definitely need an inheritance chain-like container behaviour.
What is a recommended / common pattern to transform this sort of inheritance chain to template magic?

The canonical method to remove a vtable call is to replace it with a switch statement:
enum type_e
{
type_derived,
type_derived1
};
class Base
{
public:
Base( type_e type ) : m_type( type ) {}
T foo();
private:
type_e m_type;
};
T Base::Foo()
{
switch( m_type )
{
case type_derived:
return //{...} your Derived::Foo()
case type_derived1:
return //{...} your Derived1::Foo()
}
}
The only change in the API is that instead of call new Derived() you must call new Base( type_derived ). The major disadvantage is that you now have to hold all of your additional data (formerly members of Derived1 or Derived) in Base, which may bloat the class. On the other hand you can now make a container of Base by value, and avoid the overhead of std::unique_ptr.

You could roll your own, manual vtable emulation:
class Base {
protected:
using fp_t = int(*)(Base*);
fp_t fp;
Base( fp_t p ) : fp( p ) {}
public:
int foo() { return (*fp)(this); }
};
class Derived : public Base {
static int sfoo(Base* b) { return static_cast<Derived*>(b)->foo(); }
int foo() { return 42; }
public:
Derived() : Base(&sfoo) {}
};
Live example

Related

Calling the right free function from a base pointer/reference

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);
}

How to avoid downcasting while having interface and base classes?

I'm sure i'm missing something elemental here, but i cannot get my head around it.
Let's say we have several possible implementations of a Managerclass which handles objects of type Base. It should be possible to define which implementation to use at runtime.
Based on the implementation of the Manager, they will have to set and get specific properties from Base, therefore the derivations DerivedA and DerivedB which they use internally. Is there a way to circumvent the need for downcasting the parameter in the Handle methods in order to get to the implementation-specific properties?
class Base { /* Abstract class with common properties */ };
class DerivedA : public Base { /* DerivedA-specific properties */ };
class DerivedB : public Base { /* DerivedB-specific properties */ };
class IManager { /* These functions must be implemented by every Manager implementation */
public:
virtual Base* Create() = 0;
virtual void Handle(Base*) = 0;
};
class AManager : public IManager
{
public:
Base* Create() override { return new DerivedA(); }
void Handle(Base* pFoo) override
{
// Now if we want to access pFoo's specific properties, we will need to dynamic_cast it
}
};
class BManager : public IManager
{
public:
Base* Create() override { return new DerivedB(); }
void Handle(Base* pBar) override { /* same here */ }
};
void Run(bool useAManager)
{
IManager* pManager = nullptr;
if (useAManager)
pManager = new AManager();
else
pManager = new BManager();
Base* pData = pManager->Create();
/* use Base specific properties ... */
pManager->Handle(pData);
}
Edit: Thank you all for the valuable input. I will accept #jpo38's post since it provides a possible solution to this problem. After some consideration however, I found that there is an underlying problem with the class design.
You can use the visitor pattern. In your example, this would be:
class DerivedA;
class DerivedB;
class Visitor
{
public:
virtual void visitA( DerivedA& a ) = 0;
virtual void visitB( DerivedB& b ) = 0;
};
class Base
{
public:
virtual void Accept( Visitor& visitor ) = 0;
};
class DerivedA : public Base
{
public:
virtual void Accept( Visitor& visitor ) { visitor.visitA( *this ); }
};
class DerivedB : public Base
{
public:
virtual void Accept( Visitor& visitor ) { visitor.visitB( *this ); }
};
Then, from AManager or BManager:
void Handle(Base* pFoo)
{
class MyVisitor : public Visitor
{
public:
virtual void visitA( DerivedA& a )
{
// do somethiong specific to a, you have access to DerivedA
}
virtual void visitB( DerivedB& b )
{
// do somethiong specific to b, you have access to DerivedB
}
};
MyVisitor v;
pFoo->Accept( v );
}
The disadvantage of visitor pattern is that you'll have to define a new visitor class every time you'll want to do something specific.
You can also consider doing this (but I definitely recommend visitors, very helful if you add DerivedC later or want to share some specific operation through shared visitor classes).
class Base
{
public:
virtual DerivedA* GetAsA() = 0;
virtual DerivedB* GetAsB() = 0;
};
class DerivedA : public Base
{
public:
virtual DerivedA* GetAsA() { return this; }
virtual DerivedB* GetAsB() { return NULL; }
};
class DerivedB : public Base
{
public:
virtual DerivedA* GetAsA() { return NULL; }
virtual DerivedB* GetAsB() { return this; }
};
Then, from AManager or BManager:
void Handle(Base* pFoo)
{
if ( pFoo->GetAsA() )
{
// use GetAsA to access DerivedA object avoiding downcasting
}
if ( pFoo->GetAsB() )
{
// use GetAsB to access DerivedB object avoiding downcasting
}
}
Not really. If you absolutely need to treat specific subtypes in a different way, dynamic_cast is the cleanest solution.
Strictly speaking, the real problem here starts at the word "properties". An object-oriented base class does not have properties but operations, and when you accept a Base parameter, all you are interested in are those abstract operations. In completely clean object-oriented designs, at least.
Your class design is just not cleanly object-oriented, that's all. But that's not a problem in itself. If it works for you and the code is easy to read and maintain, then everything is fine.

Template class override base class virtual function

Consider the following code:
class Base
{
public:
virtual void* allocate(){ return nullptr; }
};
template <class T> class BaseTemplate : public Base
{
public:
void* allocate() override { return new T(); }
};
class IntSpecialization : public BaseTemplate<int>
{
};
Base GetSpecialization(const int&){ return IntSpecialization(); }
The goal is to be able to use template to implement specializations, but still allow users to work using the base class interface, such as:
int a;
auto s = GetSpecialization(a);
auto p = s.allocate();
The above code does not work; s.allocate() always return nullptr for obvious reasons.
I absolutely need the GetSpecialization function to return the Base non-template class, so how do I go about this?
The Base class virtual method cannot be pure, because otherwise it becomes abstract and it will fail the compilation at GetSpecialization.
What is the best approach to solve this pattern? Using C++11?
Thanks!
Base GetSpecialization(const int&){ return IntSpecialization(); }
You're slicing the IntSpecialization object above. To make your code work, GetSpecialization must return a Base *, or a Base&. For instance, the following will work as you intended it to:
std::unique_ptr<Base> GetSpecialization(const int&)
{
return std::unique_ptr<Base>(new IntSpecialization());
}
Live demo
For the above code to work, you'll need to add a virtual destructor to Base.
class Base
{
public:
virtual void* allocate(){ return nullptr; }
virtual ~Base() = default;
};
Otherwise, when the unique_ptr goes out of scope it'll call delete ptr;, where the type of ptr is Base *, and polymorphic deletion of a derived class object through a base class pointer is undefined behavior unless the base class destructor is virtual.
Just make Base have pointer to BaseTemplate:
class BaseInterface {
public:
virtual void* allocate() = 0;
}
class Base
{
std::unique_ptr<BaseInterface> interface;
public:
Base( BaseInterface *i ) : interface( i ) {}
void* allocate(){ return interface->allocate(); }
};
template <class T> class BaseTemplate : public BaseInterface
{
public:
void* allocate() override { return new T(); }
};
class IntSpecialization : public BaseTemplate<int>
{
};
Base GetSpecialization(const int&){ return Base( new IntSpecialization ); }
Less verbose solution is to use std::function and lambda
class Base
{
public:
typedef std::function<void *()> creator;
Base( const creator &c ) : cr( c ) {}
void *allocate() { return cr(); }
private:
creator cr;
};
template<class T>
Base GetSpecialization( const T & ) { return Base( []() { return new T; } ); }

c++ design query

I am designing a framework in c++ which is supposed to provide basic functionality and act as interface for the other derived systems.
#include <stdio.h>
class Module
{
public:
virtual void print()
{
printf("Inside print of Module\n");
}
};
class ModuleAlpha : public Module
{
public:
void print()
{
printf("Inside print of ModuleAlpha\n");
}
void module_alpha_function() /* local function of this class */
{
printf("Inside module_alpha_function\n");
}
};
class System
{
public:
virtual void create_module(){}
protected:
class Module * module_obj;
};
class SystemAlpha: public System
{
public:
void create_module()
{
module_obj = new ModuleAlpha();
module_obj->print(); // virtual function, so its fine.
/* to call module_alpha_function, dynamic_cast is required,
* Is this a good practice or there is some better way to design such a system */
ModuleAlpha * module_alpha_obj = dynamic_cast<ModuleAlpha*>(module_obj);
module_alpha_obj->module_alpha_function();
}
};
main()
{
System * system_obj = new SystemAlpha();
system_obj->create_module();
}
Edited the code to be more logical and it compiles straight away. The question is, that is there a better way to design such a system, or dynamic_cast is the only solution. Also, if there are more derived modules, then for type-casting, there is some intelligence required in the base Module class.
If Derived is the only concrete instance of Base you could use static_cast instead.
Personally, I define a function, like MyCast for every specialized class. I define four overloaded variants, so that I can down-cast const and non-const pointers and references. For example:
inline Derived * MyCast(Base * x) { return static_cast<Derived *> (x); }
inline Derived const * MyCast(Base const * x) { return static_cast<Derived const *>(x); }
inline Derived & MyCast(Base & x) { return static_cast<Derived &> (x); }
inline Derived const & MyCast(Base const & x) { return static_cast<Derived const &>(x); }
And likewise for Derived2 and Base2.
The big advantage in having all four is that you will not change constness by accident, and you can use the same construct regardless if you have a pointer or a reference.
Of course, you could replace static_cast with a macro, and use dynamic_cast in debug mode and static_cast is release mode.
Also, the code above can easily be wrapped into a macro, making it easy to batch-define the functions.
Using this pattern, you could then implement your code as:
class Derived : public Base
{
public:
virtual void func2()
{
base2_obj = new Derived2();
}
void DerivedFunc()
{
MyCast(base2_obj)->Derived2Func();
}
}
The design gets much cleaner if Base does not contain the base_obj object, but rather gets a reference via a virtual method. Derived should contain a Derived2 object, like:
class Base
{
public:
virtual void func1();
private:
class Base2;
virtual Base2& get_base2();
};
class Derived : public Base
{
Derived2 derived2;
public:
Base2& get_base2() { return derived2; }
void DerivedFunc()
{
derived2->Derived2Func();
}
}
If you are worried about performance, pass the reference in the constructor of Base.
I took your code with its many compile errors and tried to simplify it. Is this what you are trying to acheive? It will compile.
class Base2 {
public:
virtual void Derived2Func(){
}
};
Base2* fnToInstantiateABase2();
class Base {
public:
Base() : base2_obj(fnToInstantiateABase2()) {
}
virtual void DerivedFunc() {
}
protected:
Base2* base2_obj;
};
class Derived : public Base {
public:
void DerivedFunc() {
base2_obj->Derived2Func(); // not possible as base2_obj is of type Base2
}
};
class Derived2 : public Base2 {
public:
void Derived2Func() {
}
};
void test() {
Base * base_obj = new Derived();
base_obj->DerivedFunc();
}
Base2* fnToInstantiateABase2() {
return new Derived2();
}

C++ Abstract type initialisation

I have a class Interface, that has pure virtual methods. In another class I have a nested type that inherits from Interface and makes it non-abstract. I use Interface as a type and use the function to initialise the type, but I am getting, cannot compile because of abstract type.
Interface:
struct Interface
{
virtual void something() = 0;
}
Implementation:
class AnotherClass
{
struct DeriveInterface : public Interface
{
void something() {}
}
Interface interface() const
{
DeriveInterface i;
return i;
}
}
Usage:
struct Usage : public AnotherClass
{
void called()
{
Interface i = interface(); //causes error
}
}
You use abstract classes as pointer and references, so you'd do
class AnotherClass
{
struct DeriveInterface : public Interface
{
void something() {}
}
DeriveInterface m_intf;
Interface &interface() const
{
return m_intf;
}
}
struct Usage : public AnotherClass
{
void called()
{
Interface &i = interface();
}
}
plus a couple of semicolons and it will work fine. Note that only pointers and references are polymorphic in C++, so even if Interface were not abstract, the code would be incorrect because of so-called slicing.
struct Base { virtual int f(); }
struct Der: public Base {
int f(); // override
};
...
Der d;
Base b=d; // this object will only have B's behaviour, b.f() would not call Der::f
You need to work with an Interface* here.