0

私はこれら 2 つのエラーについてかなり詳しく読みましたが、あらゆる努力にもかかわらず、ここで問題を確認できませんでした。結果に変化がなく、それが役立つかどうかを確認するために、コードをヘッダーガードで完全にあふれさせました。各ファイルは次の とおりです。 Mystring.cpp

#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

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

MystringDerived.h

#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

MyStringDerived.cpp

    #pragma once
#include "MyStringDerived.h"
#ifndef MYSTRINGDERIVED_CPP
#define MYSTRINGDERIVED_CPP

MyStringDerived::MyStringDerived(char * const)
{
}


MyStringDerived::~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 = "テスト"; cout<< m.getStr(); getchar(); 0 を返します。

4

1 に答える 1

2

問題は MyStringDerived.h の 2 行目にあると思います。MyString.h を含める必要があるときに、MyString.cpp を含めています。

[アップデート]

あなたがコーディングした方法では、MyString.cpp のすべての定義が MyString.obj ファイルにコンパイルされます。これは適切であり、そうあるべきです。残念ながら、#include のため、MyString.cpp のすべての定義が MyDerivedString.obj にも表示されます。

なぜこれが問題なのかを本当に理解するには、時間をかけて宣言と定義の違いを調べる必要があります。「c++ 宣言と定義」をググってください。参考になりそうな記事はこちら。http://www.cprogramming.com/declare_vs_define.html

「宣言」されたものは、害を及ぼすことなく何度でもプログラムに含めることができます。定義されているものはすべて、アプリケーションにリンクされているすべてのオブジェクト ファイルに一度だけ表示される必要があります。

これは、次の一般的なガイドラインにつながります。

ヘッダー ファイル (.h) には、宣言のみを含める必要があります。定義を含めてはなりません。定義を含めることができるのは .cpp ファイルのみです。次に、.cpp ファイルを #include しないようにする必要があります。リンク時に定義が重複しないようにする最も簡単な方法です。

于 2012-10-20T01:41:35.567 に答える