Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/154.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/templates/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ C++;模板错误_C++_Templates - Fatal编程技术网

C++ C++;模板错误

C++ C++;模板错误,c++,templates,C++,Templates,我试图用模板编写一个简单的vector类,但当我将其拆分为.h和.cpp文件时,会出现以下错误: 对vector::vector()的未定义引用 对vector::add(int)”的未定义引用 对vector::add(int)”的未定义引用 对vector::remove(int)”的未定义引用 守则: 不能将模板类的声明和实现拆分为.h和.cpp。它应该在.h中。当vector位于main()中时,编译器尝试创建类vector的实例。为此,它需要知道类的完整实现,因此您需要在.h中编写整个

我试图用模板编写一个简单的vector类,但当我将其拆分为.h和.cpp文件时,会出现以下错误:

vector::vector()的未定义引用
对
vector::add(int)”的未定义引用 对
vector::add(int)”的未定义引用
对
vector::remove(int)”的未定义引用

守则:

不能将模板类的声明和实现拆分为.h和.cpp。它应该在.h中。当vector位于main()中时,编译器尝试创建类vector的实例。为此,它需要知道类的完整实现,因此您需要在.h中编写整个模板类。

要么遵循Naveen的建议并将其保留在标题中,要么添加

template class vector<int>;
模板类向量;

到您的
.cc
文件。但是您必须为所有可能的模板参数实例化它。

有几种方法可以避免此类链接问题,这对您来说应该非常有趣 阅读

它向您解释了不同的解决方案。如果不实例化模板,则必须 将定义和实现放在.h中,但如果这样做,则必须添加以下内容

template class vector<int>;
模板类向量;
或(及)

模板类向量;

<>在您的<强> .CPP中,根据您所例示的模板。

< P>您的问题的原因在于C++中的文件组织。

关于标题和源 源文件是编译成二进制“对象文件”的文件,然后链接在一起生成最终的二进制文件(库或可执行文件)

但对于一个源使用另一个源中定义的代码,它们必须共享代码的“声明”。因此,声明必须放在我们称之为头文件的共享文件中

通常,头中的代码不是“真代码”,只是声明存在这个真代码

这就是您对自定义向量所做的:将声明放在头上,将实现放在源上,并将头包含在主向量中

关于内联 现在,一些“真正的代码”可以放在标题中,通常是在标题前面加上关键字“inline”

同样,这不是真正的代码:编译器和链接器将决定如何处理它,但它可以:

  • 将功能代码移动到“对象文件”中,并将所有其他“对象文件”链接到其中
  • 内联使用内联函数的代码
  • 这两种解决方案同时出现在上面
但是如果不使用内联函数,它很可能会从二进制文件中消失

关于模板 模板有点像声明:它们不是“真正的代码”,而是“潜在的代码”。它甚至比内联代码更“潜在”,因为模板代码需要实例化以获得正确的模板参数

与任何其他代码一样,要使用模板代码,源文件必须具有对声明的访问权限。但在本例中,模板的声明既是“潜在声明”又是“潜在实现”,编译器将为您使用的正确类型实例化它们

使用模板还有其他方法,但这是始终有效的方法

最后一条建议 在使用模板(或内联代码)时,可以非常方便地将头分解为多个文件(例如,在处理声明的循环依赖性时)

例如:

文件:MyObject.hpp

#include <MyObject_header.hpp>
#include <MyObject_source.hpp>
文件:MyObject_source.hpp

#include <MyObject_header.hpp>

MyObject::MyObject()
{
   // etc.
}

// etc.
#包括
MyObject::MyObject()
{
//等等。
}
//等等。

不正确,您只需声明希望在.C文件中定义模板类的类型。我知道。。但我不想因为这样做而把新手和模板混淆。
class MyObject
{
   // Etc.
} ;
#include <MyObject_header.hpp>

MyObject::MyObject()
{
   // etc.
}

// etc.