【问题标题】:Understanding template classes in c++ - problem with new-operator理解 C++ 中的模板类 - 新操作符的问题
【发布时间】:2010-06-28 10:49:26
【问题描述】:

亲爱的,我已经被这个问题困扰了几天,我的搜索没有成功。

我正在尝试做的事情: 我想要一个模板阅读器类 (VariableReader) 来处理不同类型的变量(通常是 unsigned int 和指向向量的指针)。

我从

开始
#ifndef READER_H_
#define READER_H_
#include <string>

namespace BAT {
template <typename variableType = unsigned int>
class VariableReader {
public:
 VariableReader<variableType>();
 VariableReader<variableType>(std::string varName);
 virtual ~VariableReader<variableType>();
 std::string getVariableName();
 void setVariableName(std::string varName);
 bool isValidVariableName(std::string varName);
 variableType getVariable();
private:
 std::string variableName;
 variableType variable;

};

}

#endif

#include "../../interface/Readers/VariableReader.h"

namespace BAT {

template<typename variableType>
VariableReader<variableType>::VariableReader() :
 variableName("") {
 // TODO Auto-generated constructor stub
}

template <typename variableType>
VariableReader<variableType>::VariableReader(std::string varName) :
 variableName(varName) {

}

template <typename variableType>
std::string VariableReader<variableType>::getVariableName() {
 return variableName;
}

template <typename variableType>
void VariableReader<variableType>::setVariableName(std::string varName) {
 if (VariableReader::isValidVariableName(varName)) {
  variableName = varName;
 }
}

template <typename variableType>
bool VariableReader<variableType>::isValidVariableName(std::string varName) {
 return varName != "";
}

template <typename variableType>
VariableReader<variableType>::~VariableReader() {
 // TODO Auto-generated destructor stub
}

}

但是,虽然它似乎可以编译,但我不能在其他项目中使用它。 编辑:忘记发布测试代码:

#include "cute.h"
#include "ide_listener.h"
#include "cute_runner.h"

#include "Readers/VariableReader.h"
using namespace BAT;

static VariableReader<int> *reader;

void setUp(){
reader = new VariableReader<int>::VariableReader();//this is problem-line
}

void thisIsATest() {
    ASSERTM("start writing tests", false);  
}

void runSuite(){
    cute::suite s;
    //TODO add your test here
    s.push_back(CUTE(thisIsATest));
    cute::ide_listener lis;
    cute::makeRunner(lis)(s, "The Suite");
}

int main(){
    runSuite();
}

我收到以下错误消息:

Building target: BAT_Tests
Invoking: GCC C++ Linker
g++ -L"/workspace/BAT/Debug Gcov" -fprofile-arcs -ftest-coverage -std=c99 -o"BAT_Tests"  ./src/Test.o   -lBAT
./src/Test.o: In function `setUp()':
/workspace/BAT_Tests/Debug Gcov/../src/Test.cpp:13: undefined reference to `BAT::VariableReader<int>::VariableReader()'
collect2: ld returned 1 exit status
make: *** [BAT_Tests] Error 1

据我了解,链接器试图找到 VariableReader 的构造函数,它没有明确定义,因为我只想有一个通用构造函数。

请帮助我了解我缺少什么。

【问题讨论】:

  • 为什么要显式调用构造函数? reader = new VariableReader&lt;int&gt;(); 应该足够了
  • 这给了我和以前一样的链接器问题。

标签: c++ class templates new-operator


【解决方案1】:

How can I avoid linker errors with my template functions? 上的 C++ FAQ Lite 部分显示了两种解决方案:

  1. 将模板类的方法移入.h 文件(或.h 文件包含的文件)。
  2. 使用template VariableReader&lt;unsigned int&gt;; 实例化.cpp 文件中的模板。

【讨论】:

  • 感谢您的链接,它帮助我了解更多。我现在在 c++ 文件中实例化了模板。然而,这对我来说似乎是模板概念的一个缺点。为什么要为每种类型定义一个模板?无论如何它现在有效,我稍后会尝试 1 号。谢谢
  • @Golden:你说得对,这是模板的一个缺点。通过将其设为仅标头,您无需显式指定它适用于哪些类型,代价是在使用您的类的任何地方都引入更多代码。不过,99% 的情况下,这是更有用的选择。
【解决方案2】:

构造函数和析构函数不需要模板参数。此外,模板类必须具有可供编译的完整源代码——您不能像使用普通类那样声明成员并在另一个翻译单元中定义它们。

【讨论】:

  • 这通常意味着你需要在头文件中实现。
  • 从 c'tor 和 d'tor 中删除模板参数用于编译,但不适用于链接。我仍然必须放置模板 VariableReader::VariableReader();在 .cpp 文件中。似乎没有什么像我想要的那样像模板一样。基本上我想要的是一个类,它需要一个模板来创建一个私有变量: VariableReaderintReader = new VariableReader(); VariableReader*> *floatReader = new VariableReader(); int var = intReader->getVariable();矢量 var2 = intReader->getVariable();
猜你喜欢
  • 2011-11-08
  • 1970-01-01
  • 2020-06-02
  • 2021-02-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-04-09
  • 1970-01-01
相关资源
最近更新 更多