我有三个文件MyType.h
,MyType.cpp
& main.cpp
#ifndef MYTYPE_H
#define MYTYPE_H
#include<iostream>
using namespace std;
template <class T,int iMax>
class A{
T iData;
public:
void vSetData(T iPar1);
void vDisplayData();
};
#endif
#include"MyType.h"
void A::vSetData(T iPar1){
if(iPar1 <= iMax)
iData = iPar1;
}
void A::vDisplayData(){
cout<<"\nData is: "<<iData<<endl;
}
#include"MyType.h"
typedef A<int,20> MyType;
int main(){
int x = 12;
MyType obj;
obj.vSetData(12);
obj.vDisplayData();
return 0;
}
错误 :10个错误。它们如下: -
#include<iostream>
using namespace std;
template <class T,int iMax>
class A{
T iData;
public:
void vSetData(T iPar1){
if(iPar1 <= iMax)
iData = iPar1;
}
void vDisplayData(){
cout<<"\nData is: "<<iData<<endl;
}
};
typedef A<int,20> MyType;
int main(){
int x = 12;
MyType obj;
obj.vSetData(12);
obj.vDisplayData();
return 0;
}
请让我知道我在 技术1
中所犯的错误答案 0 :(得分:3)
定义模板类时,编译器必须看到方法定义。所以他们必须在头文件中。
修改的
您必须包含方法实现,因此编译器可以看到它。你可以通过从另一个`MyType_impl.h“文件中包含它们来实现它:
template <class T, int iMax>
void A<T, iMax>::vDisplayData()
{
cout<<"\nData is: "<<iData<<endl;
}
答案 1 :(得分:2)
技术1对于模板是错误的。不要使用它。
将模板视为实际功能的蓝图。蓝图本身不可编辑。只有当您替换模板参数(<class T,int iMax>
)时,才会构建实际的函数。因此,编译器在尝试从模板构建函数时必须看到蓝图。为了查看蓝图,它们必须完全驻留在头文件中。
答案 2 :(得分:2)
每个方法定义都需要在其上方的完整类名称装饰:
template <typename T>
void A<T>::vSetData(T iPar1){
if(iPar1 <= iMax)
iData = iPar1;
}
template <typename T>
void A<T>::vDisplayData(){
cout<<"\nData is: "<<iData<<endl;
}
当你这样做时,你会得到其他编译错误,因为Abhineet概述了。要解决这个问题,你可以把我写的定义放到头文件中,在类声明下面,或者你可以将它放在另一个头文件(MyType_Inc.h)中,并在类声明头文件中包含/ that / header
答案 3 :(得分:1)
定义成员函数时,必须重复模板参数
template <class T,int iMax>
void A<T, iMax>::vSetData(T iPar1)
{
if(iPar1 <= iMax)
iData = iPar1;
}
这可以帮助您避免编译错误。
下一个问题是.cpp文件中定义的模板只能在该文件中使用。如果你想在其他地方使用它们,你真的应该把这些定义放在标题中。
答案 4 :(得分:1)
第一个版本有两个问题。
在类外部实现类模板的成员时,需要将其声明为模板:
template <class T,int iMax>
void A<T,iMax>::vSetData(T iPar1){
if(iPar1 <= iMax)
iData = iPar1;
}
此外,函数定义需要在实例化模板的任何编译单元中可用。实际上,这意味着您通常应该内联定义它们(在类模板定义内部,或在它之外但在头文件中并声明为inline
)。简单地在源文件中定义它们会导致链接错误。