I'm using class templates together with the singleton model.
The code compiles, but I am an undefined reference linker error, on tB::getSingleton().
I've searched around on the internet and I've came a long way, but singletons in combination with a template class is not very common.
The code is as follows
A.h:
class A{
public:
// Constructor
A() = default;
// Destructor
virtual ~A() = default;
// Gets the singleton object
template<class T>
static std::shared_ptr<A>& getSingleton(){
if (handle.get() == 0x0){
std::shared_ptr<A> inst(new T());
handle = std::move(inst);
}
return handle;
}
public:
static std::shared_ptr<A> handle;
};
A_A.h:
#include <A.h>
class A_A : public A{
public:
// Constructor
A_A() = default;
// Destructor
~A_A(); // This is defined in the .cpp file
static std::shared_ptr<A>& getSingleton()
{
if(A::handle.get() == nullptr){
std::shared_ptr<A_A> inst(new A_A());
A_A::handle = std::move(inst);
}
return A::handle;
}
};
B.h:
template<typename A_Type>
class B{
public:
// Constructor
B() = default;
// Destructor
virtual ~B() = default;
/**
* @brief Get the Singleton object
*
* @return B singleton instance
*/
template<class T>
static std::shared_ptr<B>& getSingleton(){
if (handle.get() == 0x0){
std::shared_ptr<B> inst(new T());
handle = std::move(inst);
}
return handle;
}
public:
static std::shared_ptr<B<A_Type>> handle;
};
B_B.h:
#include <A.h>
#include <B.h>
template <typename A_Type=A>
class B_B : public B<A_Type>{
public:
// Constructor
B_B() = default;
// Destructor
~B_B() = default;
/**
* @brief Get the Singleton object and sets the uart interface
*
* @return singleton instance
*/
static std::shared_ptr<B<A_Type>>& getSingleton();
};
B_B.tpp:
#include <B.h>
#include <B_B.h>
template <typename A_Type>
std::shared_ptr<B<A_Type>> B<A_Type>::handle;
/**
* @brief Get the Singleton object and sets the uart interface
*
* @return singleton instance
*/
template <typename A_Type>
std::shared_ptr<B<A_Type>>& B_B<A_Type>::getSingleton()
{
if(B<A_Type>::handle.get() == nullptr){
B<A_Type>::handle = std::move(std::static_pointer_cast<B<A_Type>>(new B_B<A_Type>()));
}
return B<A_Type>::handle;
}
C.h:
template<typename B_Type>
class C{
public:
// Constructor
C() = default;
// Destructor
virtual ~C() = default;
/**
* @brief Get the Singleton object
*
* @return C singleton instance
*/
template<class T>
static std::shared_ptr<C>& getSingleton(){
if (handle.get() == 0x0){
std::shared_ptr<C> inst(new T());
handle = std::move(inst);
}
return handle;
}
public:
static std::shared_ptr<C<B_Type>> handle;
};
C_C.h:
#include <B.h>
template <typename B_Type=B>
class C_C : public C<B_Type>{
public:
// Constructor
C_C() = default;
// Destructor
~C_C() = default;
/**
* @brief Get the Singleton object and sets the uart interface
*
* @return singleton instance
*/
static std::shared_ptr<C<B_Type>>& getSingleton();
void doStuff();
};
C_C.tpp:
#include <B.h>
#include <B_B.h>
#include <C_C.h>
template <typename B_Type>
std::shared_ptr<C<B_Type>> C<A_Type>::handle;
/**
* @brief Get the Singleton object and sets the uart interface
*
* @return singleton instance
*/
template <typename B_Type>
std::shared_ptr<C<B_Type>>& C_C<B_Type>::getSingleton()
{
if(C<B_Type>::handle.get() == nullptr){
C<B_Type>::handle = std::move(std::static_pointer_cast<C<B_Type>>(new C_C<B_Type>()));
}
return C<B_Type>::handle;
}
template <typename B_Type>
void C_C<B_Type> doStuff(){
B_Type::getSingleton();
}
main.cpp:
#include <A.h>
#include <A_A.h>
#include <B.h>
#include <B_B.h>
using tB = B_B<A_A>;
using tC = C_C<tB>;
void main(){
tC::getSingleton()->doStuff();
}
The compiler states the following:
error: no matching function for call to C<B<A> >::getSingleton()