开发者

Can template definitions of abstract (pure virtual) classes be put in source files c++

According to Storing C++ template function definitions in a .CPP file

it is easy to seprate the interface and the impleme开发者_运维百科ntation of a template class,

.h file

template<typename T> 
class foo 
{ 
   public: 
     foo();
     ~foo();
     void do(const T& t); 
}; 

.cpp file

template <typename T> 
void foo::foo() 
{ 
    // initiate 
} 

//destructor

template <typename T> 
void foo::do(const T& t) 
{ 
    // Do something with t 
} 

void foo<int> fi; 
void foo<std::string> fs; 

the trick being to specialise the template class by creating instances at the end of the .cpp file.

But what if this was a pure virtual template class

.h file

template<typename T> 
class foo 
{ 
   public:
     foo();
     ~foo(); 
     virtual void do(const T& t) = 0; 
}; 

and we derive a concrete class from this:

template<typename T> 
class foobar : public foo<T>
{ 
   public: 
     void do(const T& t); 
}; 

the source file for this class looks like

.cpp file

template <typename T> 
void foobar::do(const T& t) 
{ 
    // Do something with t 
} 

void foobar<int> fi; 
void foobar<std::string> fs;

and the source file for foo looks the same except the initiations are removed (since ofcourse now foo is an abstract class).

But there's a linker error now; foo<int>() is unresolved in the constructor of foobar<int>. This is fixed by moving the constructor and destructor of foo back to the header file from the source file.

So my question is how can we create abstract template base classes and keep the deifnition of the template class hidden in a source file??


You can explicitly instantiate a type without needing to instantiate a variable. Also, your existing code is hideously bugged and doesn't even come close to compiling.

template<typename T> 
class foo 
{ 
   public: 
     foo();
     ~foo();
     void something(const T& t); 
}; 

template <typename T> 
foo<T>::foo() 
{ 
    // initiate 
} 

//destructor

template <typename T> 
void foo<T>::something(const T& t) 
{ 
    // Do something with t 
} 
template<typename T>
foo<T>::~foo() {
}

template class foo<int>;

This will instantiate foo for int as a type but you don't need to mess around with variables.


I suggest you create an additional class for this :

#include <string>

template<typename T_Foo>
struct FooCompilation
{
  void operator()()
  {
    T_Foo foo;
    typedef typename T_Foo::T T;
    T t;
    foo.do(t);
  }
};

template FooCompilation<Foo<int> >;
template FooCompilation<Foo<std::string> >;

This should work because the compiler will try and instantiate all needed code for the code inside operator() to work.


You need to instantiate the constructor in foo.cpp as well:

template void foo<int>::foo(const int&);

You will also have to do it for foobar for it to be usable.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜