类模板分文件编写为什么会报错?
本帖最后由 Pammer 于 2020-4-27 09:43 编辑我知道会报错,只要在头文件里实现就行,但是这是为什么会这样?没有类模板是却可以正常使用。
main.cpp
#include"test.h"
int main()
{
Test<int> a;
return 0;
}
test.h
#pragma once
template<typename T = int>
class Test
{
public:
Test(T Value = 10);
T m_Value;
};
test.cpp
#include"test.h"
template<typename T>Test<T>::Test(T Arg) :m_Value(Arg) {}
.h中的模板是比较特殊的,他不会自动使用.cpp中的函数定义。如果你只引入一个模板的.h,模板会在函数调用(编译阶段)的时候进行展开,而不是去自动链接到.cpp的模板成员函数。就会在链接阶段,产生找不到模板的成员函数的问题。
这是个人理解,不对的话多多包含 本帖最后由 我的爱是你 于 2020-4-26 23:02 编辑
解决方法直接把 #include"test.cpp" 和#include"test.h" 一起包含进去就可以。
至于为啥你编译前不报错是因为编译器检索到了你 test.cpp 文件,但运行 链接时就不一样了无法找到符号链接。 庸人误我 发表于 2020-4-26 22:37
.h中的模板是比较特殊的,他不会自动使用.cpp中的函数定义。如果你只引入一个模板的.h,模板会在函数调用( ...
感谢讲解 我的爱是你 发表于 2020-4-26 22:54
解决方法直接把 #include"test.cpp" 和#include"test.h" 一起包含进去就可以。
至于为啥你编译前不报错是 ...
再问个问题,这个为什么会报错,但是编译却能正常通过? Pammer 发表于 2020-4-27 10:34
再问个问题,这个为什么会报错,但是编译却能正常通过?
没有错误
main
我的爱是你 发表于 2020-4-27 11:10
没有错误
main
感谢耐心讲解
最后,再问大佬一个问题,可以吗?
#include<iostream>
using namespace std;
class Test;
int main()
{
Test a(1);
return 0;
}
class Test
{
public:
Test(int Arg)
{
cout << Arg << endl;
}
};
这个为什么会说“使用了未定义类型“Test”” 本帖最后由 我的爱是你 于 2020-4-27 15:45 编辑
Pammer 发表于 2020-4-27 14:16
感谢耐心讲解
最后,再问大佬一个问题,可以吗?
#include
。。。。。。。。。。预留
本帖最后由 我的爱是你 于 2020-4-27 15:51 编辑
class Test; 仅声明有这个东西 但编译器并不知晓分配多少内存 所以在 class Test 定义前无法调用
程序从上向下指向 由于main 函数优先执行,所以 无法执行到类定义 class test{ }; 无法分配内存 你就要使用 自然报错
解决方法 class Test{ } 定义必须要优先与 要使用此类的函数
#include <iostream>
using namespace std;
class Test; //声明
class Test { //定义 此时优先于main
public:
Test(int Arg) {
cout << Arg << endl;
}
};
int main()
{
/*Test* a1; 如函数优先于定义 则编译器只可使用为 指针*/
Test a2(10);
return 0;
}
或者
#include <iostream>
using namespace std;
class Test { //定义
public:
Test(int Arg);//声明方法
};
int main()
{
Test a2(10);
return 0;
}
Test::Test(int Arg) { //命名空间类外实现方法
cout << Arg << endl;
}
如我在定义一个 void OBJ ( )函数,函数内调用Test 类创建对象 ;则 在void OBJ 调用前Test 类必须要定义 不能仅声明。
页:
[1]