C++ 调试对象上的LNK2005和LNK1169
我已经广泛阅读了这两个错误,但是尽管我做了很多努力,我还是看不出问题所在。我已经在我的代码中加入了大量的标题保护,看看这是否会有帮助,结果没有变化。以下是每个文件: Mystring.cppC++ 调试对象上的LNK2005和LNK1169,c++,lnk2005,C++,Lnk2005,我已经广泛阅读了这两个错误,但是尽管我做了很多努力,我还是看不出问题所在。我已经在我的代码中加入了大量的标题保护,看看这是否会有帮助,结果没有变化。以下是每个文件: Mystring.cpp #pragma once #include "MyString.h" #ifndef MYSTRING_CPP #define MYSTRING_CPP using namespace std; MyString::MyString(char chars[]){ str = (
#pragma once
#include "MyString.h"
#ifndef MYSTRING_CPP
#define MYSTRING_CPP
using namespace std;
MyString::MyString(char chars[]){
str = (char*) malloc(strlen(chars));
str = chars;
}
//etc, other methods as defined in header file
#endif
#pragma once
#include "MyStringDerived.h"
#ifndef MYSTRINGDERIVED_CPP
#define MYSTRINGDERIVED_CPP
MyStringDerived::MyStringDerived(char * const)
{
}
MyStringDerived::~MyStringDerived(void)
{
}
#endif
Mystring.h
#pragma once
#include <string.h>
#include <iostream>
#ifndef MYSTRING_H
#define MYSTRING_H
using namespace std;
class MyString {
protected:
char * str;
public:
~MyString();
MyString(char chars[]);
MyString(const char chars[]);
MyString();
int length();
void resize(int n, char c);
void clear();
bool empty();
void insert(int pos1, const MyString& str);
void insert (int pos1, const char* s);
void erase (int pos, int n);
int find(const MyString& str);
int find(const char* s);
int compare(const MyString& str);
int compare(const char* s);
const char* getStr() const;
MyString::MyString(const MyString &that);
MyString & operator=(const char chars[]);
MyString & operator=(const MyString& str);
};
#endif
#pragma once
#include "MyString.cpp"
#ifndef MYSTRINGDERIVED_H
#define MYSTRINGDERIVED_H
class MyStringDerived :
public MyString
{
public:
MyStringDerived(char chars[]);
bool operator>(MyString rhs);
bool operator>=(MyString rhs);
bool operator<(MyString rhs);
bool operator<=(MyString rhs);
bool operator==(MyString rhs);
bool operator!=(MyString rhs);
bool operator+(MyString rhs);
bool operator[](MyString rhs);
MyStringDerived(void);
~MyStringDerived(void);
};
#endif
还有我犯的错误
1>test.obj : error LNK2005: "public: int __thiscall MyString::length(void)" (?length@MyString@@QAEHXZ) already defined in MyString.obj
1>test.obj : error LNK2005: "public: void __thiscall MyString::resize(int,char)" (?resize@MyString@@QAEXHD@Z) already defined in MyString.obj
1>C:\Users\Arthur\Documents\Visual Studio 2012\Projects\Project1\Debug\Project2.exe : fatal error LNK1169: one or more multiply defined symbols found
有数百条错误行都是这样的。以我组织我的收录的方式,我绝对不认为我最终会被收录多份。我还缺什么吗?任何见解都将不胜感激。这是家庭作业(显然),所以当我在这里完成时,我肯定想真正理解这个问题。没有人知道我做错了什么
谢谢
忘记包含test.cpp。现在就这么简单:
MyStringDerived m=“测试”;我想问题出在MyStringDerived.h的第2行。当您应该包括MyString.h时,您正在包括MyString.cpp [更新] 按照您的编码方式,MyString.cpp的所有定义都被编译到MyString.obj文件中——这很好,而且应该如此。不幸的是,由于您的#include,MyString.cpp的所有定义也出现在MyDerivedString.obj中 要真正理解为什么这是一个问题,您需要花一些时间研究声明和定义之间的区别——只需谷歌“c++声明vs定义”。这里有一篇文章可能会有所帮助 任何“声明”的内容都可以一次又一次地包含到程序中,而不会造成任何伤害。定义的任何内容都必须在链接到应用程序的所有对象文件中显示一次且仅显示一次 这导致了以下一般准则:
头文件(.h)只能包含声明。它不能包含任何定义。只有.cpp文件可以包含定义。那么你必须确保永远不要包含.cpp文件。这是确保链接时不会有重复定义的最简单方法。谢谢!这消除了大部分错误!在我继续之前,我想问一个问题——为什么这很重要?如果我包含cpp,然后包含.h,那么我最终会在该子类中包含.h,不是吗?还是比这更复杂?另外,剩下的错误只有三个:2>test.obj:error LNK2005:“public:u thiscall MyStringDerived::MyStringDerived(char*const)”(?0 MyStringDerived@@QAE@QAD@Z) 已在MyStringDerived.obj 2>test.obj中定义:错误LNK2005:“public:u thiscall MyStringDerived::~MyStringDerived(void)”(?1 MyStringDerived@@QAE@XZ)已在MyStringDerived.obj 2>C:\Users\Arthur\Documents\Visual Studio 2012\Projects\Project1\Debug\Project2.exe中定义:致命错误LNK1169:找到一个或多个多重定义符号我将更新答案并说明原因。对于剩下的错误,我怀疑您在test.cpp中也在做同样的事情-包括MyStringDerived.cpp而不是MyStringDerived.hYes,就是这样。我想从现在起我能记得这就是它的工作原理,但如果我明白为什么会这样,那会有所帮助。非常感谢您的帮助,我期待这个答案的扩展。