I have been studying the CRTP lately and have come up of an idea to create a generic base template class using CRTP.
// Example.h
namespace A {
template <class TClass, typename T>
class Example {
public:
Example(T &someStruct) : m_someStruct_(someStruct)
{
}
~Example()
{
DoThis();
}
public:
void DoThis()
{
static_cast<TClass*>(this)->DoThat(m_someStruct_);
}
private:
T m_someStruct_;
};
}
// AsArgument.h
namespace A {
class AsArgument : public Example <AsArgument, SomeStruct> {
friend class Example <AsArgument, SomeStruct>;
private:
void DoThat(SomeStruct &someFun)
{
// Do something to someFun object.
// yehey(someFun);
printf("I want to do that! \n");
}
};
}
My goal is to use the base class object to access the derived class' functions and at the same time, separate the base and derived's implementation by including only the base class' header file and forward declare the derived class as a template argument.
I know the basics of what I can do with incomplete types but I can't seem to find information about templates.
Is it valid to forward declare the class TDerived argument instead of including the header file?
// SomeFile.cpp
#include "Example.h"
class A::AsArgument; // Forward declare this instead of including the AsArgument.h header file
namespace B {
void SomeClass::DoSomething()
{
SomeStruct fun;
Example <AsArgument, SomeStruct> example(fun);
}
}
I am not sure if this is a good design in creating a generic base template class, but my goal after establishing the base class is to easily create derived classes out of it and define the base class implementation on compile time. It's actually some sort of a combination of RAII and CRTP.
I can actually achieve this by including the "AsArgument.h" file with "Example.h" but the separation between the base and the implementation is lost. And I keep getting compile error when I try to forward declare the AsArgument class (probably because of namespace issues I'm not fully aware of).
Any advise or is this kind of design even efficient and valid?