Pammer 发表于 2020-4-26 21:45

类模板分文件编写为什么会报错?

本帖最后由 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) {}

庸人误我 发表于 2020-4-26 22:37

.h中的模板是比较特殊的,他不会自动使用.cpp中的函数定义。如果你只引入一个模板的.h,模板会在函数调用(编译阶段)的时候进行展开,而不是去自动链接到.cpp的模板成员函数。就会在链接阶段,产生找不到模板的成员函数的问题。
这是个人理解,不对的话多多包含

我的爱是你 发表于 2020-4-26 22:54

本帖最后由 我的爱是你 于 2020-4-26 23:02 编辑

解决方法直接把 #include"test.cpp" 和#include"test.h" 一起包含进去就可以。
至于为啥你编译前不报错是因为编译器检索到了你 test.cpp 文件,但运行 链接时就不一样了无法找到符号链接。

Pammer 发表于 2020-4-27 09:43

庸人误我 发表于 2020-4-26 22:37
.h中的模板是比较特殊的,他不会自动使用.cpp中的函数定义。如果你只引入一个模板的.h,模板会在函数调用( ...

感谢讲解

Pammer 发表于 2020-4-27 10:34

我的爱是你 发表于 2020-4-26 22:54
解决方法直接把 #include"test.cpp" 和#include"test.h" 一起包含进去就可以。
至于为啥你编译前不报错是 ...


再问个问题,这个为什么会报错,但是编译却能正常通过?

我的爱是你 发表于 2020-4-27 11:10

Pammer 发表于 2020-4-27 10:34
再问个问题,这个为什么会报错,但是编译却能正常通过?

没有错误

main

Pammer 发表于 2020-4-27 14:16

我的爱是你 发表于 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:40

本帖最后由 我的爱是你 于 2020-4-27 15:45 编辑

Pammer 发表于 2020-4-27 14:16
感谢耐心讲解
最后,再问大佬一个问题,可以吗?
#include

。。。。。。。。。。预留

我的爱是你 发表于 2020-4-27 15:46

本帖最后由 我的爱是你 于 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;
}

我的爱是你 发表于 2020-4-27 15:55

如我在定义一个 void OBJ ( )函数,函数内调用Test 类创建对象 ;则 在void OBJ 调用前Test 类必须要定义 不能仅声明。
页: [1]
查看完整版本: 类模板分文件编写为什么会报错?