C++ I';我得到一个“a”;“重新定义”;类中每个方法的错误
对于类中的每个方法,我都会得到一个重新定义错误。我试图将.cpp代码放在标题中“include Algebra.cpp”的位置,但没有改变任何东西C++ I';我得到一个“a”;“重新定义”;类中每个方法的错误,c++,oop,C++,Oop,对于类中的每个方法,我都会得到一个重新定义错误。我试图将.cpp代码放在标题中“include Algebra.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 de
// 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
//这是.h文件
#ifndef代数
#定义代数
#包括
模板
类矩阵{
双**矩阵;
void debug_print();
公众:
矩阵();
矩阵(双(&_矩阵)[行][cols]);
~Matrix();
双重计算_行列式();
};
#包括“代数.cpp”
#恩迪夫
//这是.cpp文件
#包括“代数h”
#包括
模板
矩阵::矩阵(){…}
//我已经定义了下面所有的方法。。
首先,该模板函数定义属于头文件中,该文件可通过#包括“algebra.h”
拉入任何需要的位置
此特定设置出现问题的原因是,正如一些评论所建议的,您正在编译包含该模板函数定义的.cpp文件。编译器编译“algebra.cpp”时,首先会在文件顶部看到#include
指令,然后从“algebra.h”中提取文本。就其本身而言,这很好,但在“algebra.h”的末尾,它会看到#include“algebra.cpp”
。所以它把文本从那里拉了进来
现在它正在编译“代数.cpp”中的“代数.cpp”。“algebra.h”中的include-guard在这里起作用,因此“algebra.h”的内容没有重新定义。然后它会看到Matrix::Matrix()
的定义。到目前为止还行
现在到了通过#include
指令输入的代码的末尾,因此它继续在“algebra.cpp”中编译代码,并且再次看到矩阵::矩阵()
的定义,这就是编译器抱怨的重新定义
这就是为什么你不应该那样做
有些人喜欢将类模板的成员函数的定义放在与定义类模板的头文件不同的文件中。没关系,但是不要编译那个文件;它只能作为使用它的头的一部分进行编译。作为一个实际问题,这意味着给它一个扩展名,明确它不是一个单独编译的源文件。当我使用这种方法时,我使用“.inl”作为扩展。如果您将“algebra.cpp”的名称更改为“algebra.inl”,并确保您没有告诉编译器编译“algebra.inl”,那么这个问题应该会消失。“我试图将.cpp代码放在标题中“include algebra.cpp”的位置,但没有更改任何内容。”
\include
正是这样做的,所以很明显,它没有改变任何事情。您将.cpp文件包含在标题中正是问题的原因。不要那样做。另外:为什么要在.h文件中包含一个.cpp文件?你知道,只要在头文件中实现模板,就可以结束这种疯狂行为,对吗?不,相反。不要编译代数.cpp
。问题是,许多IDE将编译代数.cpp
文件。如果您想以这种方式分离声明和实现,请确保未编译Algebra.cpp
。因此,更改文件扩展名是一个好主意,可以清楚地表明它不是翻译单元。例如到.inl
。感谢您的详细解释!
// 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..