C++:错误重定义和先前声明

C++ : Error Redefinition & Previously Declared

本文关键字:声明 定义 错误 C++      更新时间:2023-10-16

我的课程已经完成了一半。我无法理解我收到的错误背后的逻辑。我已经尝试通过在 Array.h 文件底部使用适当的指令来对抗它。我在所有函数中收到以下 2 个错误:

  1. 注意:'const T& udbhavAg::Container::Array::operator const' 之前在这里声明 const T &Array::operator[](int index( const {
  2. error: 重新定义 'const T& udbhavAg::Container::Array::operator const' const T &Array::operator[](int index( const {

我的问题如下:

  1. 为什么文件被声明两次?
  2. 为什么要重新定义它们?

主.cpp

#include <iostream>
#include "Point.h"
#include "Line.h"
#include "Circle.h"
#include "Array.h"
#include "ArrayException.h"
using namespace std;
using namespace udbhavAg::CAD;
using namespace udbhavAg::Container;
using namespace udbhavAg;
int main()
{
Array<Point> points(10);
return 0;
}

Array.h

#include "Point.h"
#include <cstring>
#include "ArrayException.h"
#ifndef ARRAY_H
#define ARRAY_H
//#include "Array.cpp"
namespace udbhavAg
{
namespace Container
{
template <typename T>
class Array {
private:
T *m_data;
int m_size;
public:
Array();
Array(int size);
Array(const Array &obj);
virtual ~Array();
//const Array operator= ( const Array & source);
Array<T> &operator=(const Array &source);
int Size() const;
void setElement(int index, T p);
T &getElement(int index) const;
T &operator[](int index);
const T &operator[](int index) const;
};
}
}
#ifndef Array_cpp // Must be the same name as in source file #define
#include "Array.cpp"
#endif
#endif ARRAY_H

阵列.cpp

#include "Array.h"
#include "ArrayException.h"

namespace udbhavAg
{
namespace Container
{
template<typename T>
Array<T>::Array():m_size(3),m_data(new T[m_size]) {}
template<typename T>
Array<T>::Array(int size): m_size(size), m_data(new T[m_size]) {}
template<typename T>
Array<T>::~Array()
{
delete[] m_data;
cout << "Destructor called" << endl;
}
template<typename T>
Array<T>::Array(const Array &obj) {
m_size = obj.m_size;
m_data = new CAD::Point[m_size];
for (int i = 0; i < m_size; i++)
{
m_data[i] = obj.operator[](i);
}
}
template<typename T>
int Array<T>::Size() const
{
return m_size;
}
template<typename T>
T &Array<T>::getElement(int index) const
{
try
{
if (index >= m_size || index < 0)
{
throw (OutofBoundsException(index));
}
else
{
return m_data[index];
}
}
catch (ArrayException &error)
{
cout << error.GetMessage();
}
}
template<typename T>
void Array<T>::setElement(int index, T p)
{
try
{
if (index >= m_size || index < 0)
{
//                    OutofBoundsException error = OutofBoundsException(index);
//                    ArrayException& abc = error;
throw (OutofBoundsException(index));
}
else
{
m_data[index] = p;
}
}
catch (ArrayException &error)
{
cout << error.GetMessage();
}
}
template<typename T>
Array<T> & Array<T>::operator=(const Array &source)
{
if(&source != this){ //edited self assignment test
if(m_size != source.m_size){//diff sized arrays
delete [] m_data; //reclaim space
m_size = source.m_size;
m_data = new CAD::Point[m_size]; //space created
}
}
for(int i=0; i<m_size; i++){
m_data[ i ] = source.m_data[i];}
return *this;     //enables cascading a=b=c
}
template<typename T>
T &Array<T>::operator[](int index) {
try
{
if (index >= m_size || index < 0)
{
//                        OutofBoundsException error = OutofBoundsException(index);
//                        ArrayException& abc = error;
throw (OutofBoundsException(index));
}
else
{
return m_data[index];
}
}
catch (ArrayException &error)
{
cout << error.GetMessage();
}
}
template<typename T>
const T &Array<T>::operator[](int index) const {
try
{
if (index >= m_size || index < 0)
{
//                        OutofBoundsException error = OutofBoundsException(index);
//                        ArrayException& abc = error;
throw (OutofBoundsException(index));
}
else
{
return m_data[index];
}
}
catch (ArrayException &error)
{
cout << error.GetMessage();
}
}
}
}

可能是因为在 Array.h 中:

#ifndef Array_cpp // Must be the same name as in source file #define
#include "Array.cpp"
#endif

所以数组.cpp#include Array.h因为未定义Array_cpp#include Array.cpp

不要在头文件中包含源文件

为什么在 Array.h 中

#ifndef ARRAY_H
#define ARRAY_H

不在文件的开头?


所以可能的独家解决方案是:

  • 以删除数组开头的#include "Array.h".cpp
  • #define Array_cpp添加为 Array 中的第一行.cpp

在这两种情况下,您都不得在 Makefile 或等效文件中编译 Array.cpp,也不得与其链接。

但最好的方法是在 Array.h 中替换

#ifndef Array_cpp // Must be the same name as in source file #define
#include "Array.cpp"
#endif

通过文件数组中的定义.cpp并删除文件数组.cpp。

模板类很特殊,所有模板方法都必须在头文件中定义,并且只能在头文件中定义,而不是在同样编译为"普通"源文件的源文件中,编译器会为您完成这些工作