C++中是否可以将抽象(纯虚)类的模板定义放在源文件中?

3
根据将C++模板函数定义存储在.CPP文件中的说法,分离模板类的接口和实现非常容易。 .h文件:
template<typename T> 
class foo 
{ 
   public: 
     foo();
     ~foo();
     void do(const T& t); 
}; 

.cpp 文件

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; 

技巧就是通过在.cpp文件的末尾创建实例来专门化模板类。

但如果这是一个纯虚拟模板类呢?

.h 文件

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

我们从这个类中派生出一个具体的类:
template<typename T> 
class foobar : public foo<T>
{ 
   public: 
     void do(const T& t); 
}; 

这个类的源文件看起来像这样: .cpp文件
template <typename T> 
void foobar::do(const T& t) 
{ 
    // Do something with t 
} 

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

而foo的源文件看起来一样,只是初始化被删除了(因为现在foo是一个抽象类)。

但现在有一个链接器错误;在foobar<int>的构造函数中无法解析foo<int>()。这可以通过将foo的构造函数和析构函数从源文件移回头文件中来解决。

那么我的问题是,我们如何创建抽象模板基类并将模板类的定义隐藏在源文件中?


非抽象的 foo<T> 是否链接? - Marcelo Cantos
3个回答

2
我建议你为此创建一个额外的类:
```html

我建议您为此创建一个额外的类:

```
#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> >;

这应该行得通,因为编译器会试图实例化所有需要的代码,以使operator()内部的代码正常工作。


2
你可以显式地实例化一个类型,而无需实例化一个变量。此外,你现有的代码存在严重错误,甚至无法编译。
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>;

这将实例化int类型的foo,但您不需要操作变量。

1

你还需要在foo.cpp中实例化构造函数:

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

你还需要为foobar做同样的事情,以便它能够使用。


谢谢,这个方法可行,这意味着所有抽象类的成员都需要在.cpp文件中初始化,对于所有不同的特化都是如此。真是太麻烦了!你知道有没有更优雅的方法来分离模板类的接口和实现? - aukm

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接