我收到类中每个方法的"redefinition of"错误

I'm getting a "redefinition of" error for every method in the class

本文关键字:redefinition of 错误 方法      更新时间:2023-10-16

我收到类中每个方法的重新定义错误。我试图将.cpp代码放在"包含代数.cpp"所在的标题中,但没有改变任何事情。

// This is the .h file
#ifndef ALGEBRA_H
#define ALGEBRA_H
#include <iostream>
template <size_t rows, size_t cols>
class Matrix {
double** matrix;
void debug_print();    
public:
Matrix();
Matrix(double (&_matrix)[rows][cols]);
~Matrix();
double calculate_determinant();
};
#include "Algebra.cpp"
#endif
// This is the .cpp file
#include "Algebra.h"
#include <cassert>
template <size_t rows, size_t cols>
Matrix<rows, cols>::Matrix() {...}
// I have defined all the methods below..

首先,该模板函数定义属于文件,该文件通过#include "algebra.h"的任何需要的地方拉入。

您在此特定设置中遇到问题的原因是,正如一些评论所建议的那样,您正在编译包含该模板函数定义的.cpp文件。当编译器编译"algebra.cpp"时,它首先看到文件顶部的#include指令,并从"algebra.h"中提取文本。就目前而言,这很好,但是在"代数.h"的末尾,它看到了#include "algebra.cpp".所以它从那里拉入文本。

现在它在"代数.cpp"中编译"代数.cpp"。"algebra.h"中的包含守卫在这里工作,因此没有重新定义"algebra.h"的内容。然后它看到了Matrix<rows, cols>::Matrix()的定义.到目前为止,还好。

现在它到了通过#include指令传入的代码的末尾,所以它继续编译 "代数.cpp" 中的代码,它再次看到了Matrix<rows, cols>::Matrix()的定义,这就是编译器抱怨的重新定义。

这就是为什么你不应该这样做。

有些人喜欢将类模板的成员函数的定义放在与定义类模板的标头不同的文件中。没关系,但不要编译该文件;它应该只编译为使用它的标头的一部分。作为一个实际问题,这意味着给它一个扩展名,清楚地表明它不是一个要单独编译的源文件。当我使用这种方法时,我使用".inl"作为扩展名。如果你把"algebra.cpp"的名字改成"algebra.inl",并确保你没有告诉编译器编译"algebra.inl",这个问题应该会消失。