我是C ++的初学者,但我有一些使用Java的经验。我收到一些我不明白的错误。我附上了错误控制台的图片和它下面的代码。
Error 1 error LNK2005: "public: __thiscall VectorDouble::VectorDouble(void)" (??0VectorDouble@@QAE@XZ) already defined in Main.obj C:\Users\carrea\Code\Visual Studio\COMP201\Lab8_VectorDoubleClass\VectorDouble.obj Lab8_VectorDoubleClass
Error 2 error LNK2005: "public: __thiscall VectorDouble::VectorDouble(int)" (??0VectorDouble@@QAE@H@Z) already defined in Main.obj C:\Users\carrea\Code\Visual Studio\COMP201\Lab8_VectorDoubleClass\VectorDouble.obj Lab8_VectorDoubleClass
....
还有10个这样的错误和
Error 13 error LNK1169: one or more multiply defined symbols found C:\Users\carrea\Code\Visual Studio\COMP201\Lab8_VectorDoubleClass\Debug\Lab8_VectorDoubleClass.exe 1 1 Lab8_VectorDoubleClass
Main.cpp的
#include "VectorDouble.cpp"
using namespace std;
void printVD(const VectorDouble& v);
int main()
{
VectorDouble p;
p.push_back(1);
p.push_back(4);
p.push_back(3);
VectorDouble v(p);
printVD(v);
printVD(p);
}
void printVD(const VectorDouble& v)
{
int n = v.size();
for(int i = 0; i<n; i++)
{
cout << v.getElementAt(n) << " ";
}
cout << endl;
}
VectorDouble.h
#pragma once
#include <fstream>
#include <iostream>
#include <string>
#include <cstdlib>
#include <iomanip>
#include <vector>
#include <sstream>
using namespace std;
class VectorDouble
{
public:
VectorDouble(void);
~VectorDouble(void);
VectorDouble(int intSize);
// Copy constructor
VectorDouble(const VectorDouble& vd);
// = override
void operator =(const VectorDouble& RIGHT_SIDE);
private:
double *dArray;
int count, max_count;
public:
// returns number of occupied cells
int size(void) const;
// Returns total number of cells
int capacity(void) const;
// Adds an element to array
void push_back(double num);
// Resizes the array to be double the original max_count
void resize(void);
// Returns element at specified index
double getElementAt(int i) const;
// Requests that the capacity of the allocated storage space for the elements of the vector container be at least enough to hold n elements
void reserve(int n);
private:
// Sets every element to 0
void clear(void);
};
VectorDouble.cpp
#pragma once
#include "VectorDouble.h"
using namespace std;
VectorDouble::VectorDouble(void)
{
max_count = 100;
count = 0;
dArray = new double[max_count];
clear();
}
VectorDouble::VectorDouble(int intSize)
{
max_count = intSize;
dArray = new double[max_count];
clear();
}
VectorDouble::~VectorDouble(void)
{
cout << "vector with " << this->count << " is destroyed";
}
// Copy constructor
VectorDouble::VectorDouble(const VectorDouble& vd)
{
int mcVD = vd.capacity(), i=0;
max_count = mcVD;
dArray = new double[max_count];
clear();
while(i<max_count)
{
dArray[i] = vd.getElementAt(i);
i++;
}
}
// = override
void VectorDouble::operator =(const VectorDouble& RIGHT_SIDE)
{
int rightCount = RIGHT_SIDE.size(), i=0;
while(rightCount>max_count)
{
resize();
}
while(i<rightCount)
{
dArray[i] = RIGHT_SIDE.getElementAt(i);
i++;
}
count = i;
}
// returns number of occupied cells
int VectorDouble::size(void) const
{
return count;
}
// Returns total number of cells
int VectorDouble::capacity(void) const
{
return max_count;
}
// Adds an element to array
void VectorDouble::push_back(double num)
{
if(count==max_count)
{
resize();
}
dArray[count] = num;
count++;
}
// Resizes the array to be double the original max_count
void VectorDouble::resize(void)
{
double *p = new double[max_count*2];
for(int i = 0; i < count; i++)
{
p[i] = dArray[i];
}
dArray = p;
max_count*=2;
delete p;
}
// Returns element at specified index
double VectorDouble::getElementAt(int i) const
{
return dArray[i];
}
// Requests that the capacity of the allocated storage space for the elements of the vector container be at least enough to hold n elements
void VectorDouble::reserve(int n)
{
while(n<max_count)
resize();
}
// Sets every element to 0
void VectorDouble::clear(void)
{
for(int i = 0; i < max_count; i++)
dArray[i] = 0;
}
非常感谢任何帮助......
答案 0 :(得分:27)
您应该在"VectorDouble.h"
中加入"VectorDouble.cpp"
而不是Main.cpp
。
与许多其他语言相比,包含文件的整个概念在C ++中相当破碎。
首先,C ++将事物划分为“声明”和“定义”。你可能只对程序中的某个东西有一个定义,但是你想要的声明数量很多。在VectorDouble.cpp
文件中,您要定义内容,并在VectorDouble.h
文件中声明内容。
C ++中的#include
指令简单而愚蠢。遇到这种情况时,编译器会有效地进行简单的文本替换。 #include
指令将替换为您包含的文件的内容。
当您#include
定义文件时,这意味着您可以在#include
处完全定义它们。这就是为什么你不应该包括"VectorDouble.cpp"
。由于您可能还将该文件编译为单独的文件,因此您最终会得到至少两份所有定义的副本。
在谈论某些事情时,整个宣言与定义二分法变得非常混乱。例如,如果函数声明为inline
,则函数体不再被认为是definition
。这意味着您可以根据需要使用已声明为inline
的函数体的副本。所需要的只是所有定义都相同。
同样,即使包含函数体,声明模板函数也是一个声明。这是因为声明导致没有生成代码,只有模板实例化导致代码生成。这就是决定某件事是宣言还是定义的真正试金石。如果它导致空间被分配或者当时正在生成实际代码,那么它就是一个定义,否则就是一个声明。
答案 1 :(得分:6)
您收到的错误是链接器错误,告诉您编译器正在为某些成员函数找到多个定义。如果你看一下错误信息的这个块:
public: __thiscall VectorDouble::VectorDouble(void)" (??0VectorDouble@@QAE@XZ) already defined in Main.obj
你可以看到埋藏在那里的事实是它正在讨论已经定义的构造函数VectorDouble::VectorDouble()
。
我认为你遇到的特殊问题是在main.cpp中的这一行:
#include "VectorDouble.cpp"
问题是这包括 source 文件,而不是 header 文件。因此,当您编译main.cpp时,您将编译所有main,以及VectorDouble.cpp中的所有定义。当链接器尝试将它与编译VectorDouble.cpp时生成的目标文件链接起来时,它将找到所有内容的两个定义 - 一个来自VectorDouble.cpp,另一个来自main.cpp。
要解决此问题,请将此行更改为
#include "VectorDouble.h"
这应该可以解决您的问题。但更一般地说,实际上#include
.cpp文件非常罕见。你几乎总是包括标题,而不是来源。
希望这有帮助!
答案 2 :(得分:1)
Main.cpp不应该是#include
- VectorDouble.cpp;它应#include
VectorDouble.h。如果要链接两个.cpp文件,链接器会在VectorDouble.cpp中看到所有内容(一次单独出现,一次出现在#include
- 来自Main.cpp)。
答案 3 :(得分:0)
当我尝试在名为 PresentDataStruct.h 的单独文件中定义类并且还创建了 PresentDataStruct.cpp 文件时,我遇到了类似的链接错误。
以下是 PresentDataStruct.h 的内容:
#pragma once
#include <string>
using namespace System;
ref class CPresentDataStruct
{
public:
CPresentDataStruct();
~CPresentDataStruct();
public:
void SomeActionOnData();
public:
System::String^ Name;
DateTime^ BirthDay;
};
void CPresentDataStruct::SomeActionOnData()
{
//TO DO here
}
CPresentDataStruct::CPresentDataStruct()
{
}
CPresentDataStruct::~CPresentDataStruct()
{
}
在 PresentDataStruct.cpp 中,它有一行:
include "PresentDataStruct.h"
然后我添加include "PresentDataStruct.h"
时出现链接错误
到 maindialog.h 文件。
所以我把它移到 PresentDataStruct.cpp 文件中,链接错误消失了:
void CPresentDataStruct::SomeActionOnData()
{
//TO DO here
}
CPresentDataStruct::CPresentDataStruct()
{
}
CPresentDataStruct::~CPresentDataStruct()
{
}