C++ 抽象(纯虚拟)类的模板定义可以放在源文件c++;

C++ 抽象(纯虚拟)类的模板定义可以放在源文件c++;,c++,visual-c++,templates,C++,Visual C++,Templates,据 很容易分离接口和模板类的实现 .h文件 template<typename T> class foo { public: foo(); ~foo(); void do(const T& t); }; template <typename T> void foo::foo() { // initiate } //destructor template <typename T>

很容易分离接口和模板类的实现

.h文件

template<typename T> 
class foo 
{ 
   public: 
     foo();
     ~foo();
     void do(const T& t); 
}; 
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; 
template<typename T> 
class foo 
{ 
   public:
     foo();
     ~foo(); 
     virtual void do(const T& t) = 0; 
}; 
template <typename T> 
void foobar::do(const T& t) 
{ 
    // Do something with t 
} 

void foobar<int> fi; 
void foobar<std::string> fs;
模板
福班
{ 
公众:
foo();
~foo();
无效do(常数T&T);
}; 
.cpp文件

template<typename T> 
class foo 
{ 
   public: 
     foo();
     ~foo();
     void do(const T& t); 
}; 
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; 
template<typename T> 
class foo 
{ 
   public:
     foo();
     ~foo(); 
     virtual void do(const T& t) = 0; 
}; 
template <typename T> 
void foobar::do(const T& t) 
{ 
    // Do something with t 
} 

void foobar<int> fi; 
void foobar<std::string> fs;
模板
void foo::foo()
{ 
//发起
} 
//析构函数
模板
void foo::do(常量T&T)
{ 
//用t做点什么
} 
void foo fi;
void foo fs;
诀窍是通过在.cpp文件末尾创建实例来专门化模板类

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

.h文件

template<typename T> 
class foo 
{ 
   public: 
     foo();
     ~foo();
     void do(const T& t); 
}; 
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; 
template<typename T> 
class foo 
{ 
   public:
     foo();
     ~foo(); 
     virtual void do(const T& t) = 0; 
}; 
template <typename T> 
void foobar::do(const T& t) 
{ 
    // Do something with t 
} 

void foobar<int> fi; 
void foobar<std::string> fs;
模板
福班
{ 
公众:
foo();
~foo();
虚空do(常数T&T)=0;
}; 
我们从中派生出一个具体的类:

template<typename T> 
class foobar : public foo<T>
{ 
   public: 
     void do(const T& t); 
}; 
模板
foobar类:公共foo
{ 
公众:
无效do(常数T&T);
}; 
此类的源文件如下所示

.cpp文件

template<typename T> 
class foo 
{ 
   public: 
     foo();
     ~foo();
     void do(const T& t); 
}; 
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; 
template<typename T> 
class foo 
{ 
   public:
     foo();
     ~foo(); 
     virtual void do(const T& t) = 0; 
}; 
template <typename T> 
void foobar::do(const T& t) 
{ 
    // Do something with t 
} 

void foobar<int> fi; 
void foobar<std::string> fs;
模板
void foobar::do(常量T&T)
{ 
//用t做点什么
} 
无效foobar fi;
无效foobar fs;
foo的源文件看起来是一样的,只是删除了初始化(当然,现在foo是一个抽象类)

但是现在有一个链接器错误
foo()
foobar
的构造函数中未解析。这是通过将foo的构造函数和析构函数从源文件移回头文件来修复的


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

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

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

您还必须为
foobar
执行此操作才能使其可用。

我建议您为此创建一个附加类:

#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> >;
#包括
模板
结构编译
{
void运算符()()
{
杜富福;
typedef typename T_Foo::T;
T;
foo.do(t);
}
};
模板编制;
模板编制;

这应该是可行的,因为编译器将尝试实例化运算符()中的代码所需的所有代码。

您可以显式实例化类型,而无需实例化变量。此外,您现有的代码存在可怕的bug,甚至无法进行编译

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>;
模板
福班
{ 
公众:
foo();
~foo();
使某物无效(const T&T);
}; 
模板
foo::foo()
{ 
//发起
} 
//析构函数
模板
void foo::某物(const T&T)
{ 
//用t做点什么
} 
模板
foo::~foo(){
}
模板类foo;

这将把整型的foo实例化为一个类型,但您不需要处理变量。

非抽象
foo
链接是否有效?谢谢,这意味着对于所有不同的专业,抽象类的所有成员都需要在.cpp文件中启动。多痛苦啊!您知道一种更优雅的方法来分离模板类的接口和实现吗?