2012-03-31 13 views
4

これら2つのファイルherehereを使用します。リンク時に多重定義エラーが発生するのはなぜですか?

私は2つの別々のファイルにクラスを作成しました:今、私は別のファイルにこのクラスを使用したい

modul1.h

#ifndef MODUL1_H 
#define MODUL1_H 

#include <iostream> 
#include <fstream> 

#include "easylogger.h" 

class Modul1 
{ 
    public: 
     Modul1(std::string name); 
    protected: 
    private: 
     easylogger::Logger *log; 
}; 

#endif // MODUL1_H 

とmodul1.cpp

#include "modul1.h" 

Modul1::Modul1(std::string name):log(new easylogger::Logger(name)) 
{ 
    //ctor 
    //std::ofstream *f = new std::ofstream(name.c_str(), std::ios_base::app); 
    //log->Stream(*f); 
    //log->Level(easylogger::LEVEL_DEBUG); 
    //LOG_DEBUG(*log, "ctor ende!"); 
} 

(メイン.cpp):

#include "modul1.h" 

int main() 
{ 
    std::cout << "Hello world!" << std::endl; 
    Modul1 mod1("test.log"); 
    return 0; 
} 

私は、次のMakefileでそれをコンパイルすると、私はエラー「の...複数の定義」を取得:

g++ main.o modul1.o -o main modul1.o: In function easylogger::Logger::Format(std::basic_string<char, std::char_traits<char>, std::allocator<char> > const&)': modul1.cpp:(.text+0x0): multiple definition of easylogger::Logger::Format(std::basic_string, std::allocator > const&)' main.o:main.cpp:(.text+0x0): first defined here modul1.o: In function easylogger::Logger::WriteLog(easylogger::LogLevel, easylogger::Logger*, char const*, unsigned int, char const*, char const*)': modul1.cpp:(.text+0x2a): multiple definition of easylogger::Logger::WriteLog(easylogger::LogLevel, easylogger::Logger*, char const*, unsigned int, char const*, char const*)' main.o:main.cpp:(.text+0x2a): first defined here collect2: ld returned 1 exit status

(最初のIでのコードでそれをコンパイル::ブロックと同じエラーを得た)

このリンクエラーが発生しないようにModul1を変更するにはどうすればよいですか?私はそれが重要だとは思わないが、私はグラムで、いくつかのUbuntuの64bit版を使用しています++ 4.4.3

のMakefile:

CC=g++ 
CFLAGS=-c -Wall 

all: log_test 

log_test: main.o easylogger.h modul1.o 
    $(CC) main.o modul1.o -o main 

main.o: main.cpp modul1.h 
    $(CC) $(CFLAGS) main.cpp 

modul1.o: modul1.cpp modul1.h 
    $(CC) $(CFLAGS) modul1.cpp 
+5

ページ全体を書きますが、完全なエラーメッセージを投稿しないのはなぜですか? –

+0

複数の定義...何ですか?ここで「何」が最も重要な部分です。 – Cornstalks

+2

また、なぜmain.oはmodul1.cppを参照していますか? – Cornstalks

答えて

4

あなたはこの、easylogger.h(その結果、easylogger-inl.h)を構築している方法は、modul1.hのために1回、2回含まれますし、一度main.cppに

のためにそれのあなたの使い方が間違っています。しかし、あなたはそれを動作させるために、これを行うことができます。modul1.hで

(の#include「easylogger.h」を削除します)、それはこの

#ifndef MODUL1_H 
#define MODUL1_H 

#include <iostream> 
#include <fstream> 
//#include "easylogger.h" 

namespace easylogger { class Logger; }; 

class Modul1 
{ 
    public: 
     Modul1(std::string name); 
    protected: 
    private: 
     easylogger::Logger *log; 
}; 

#endif // MODUL1_H 

とmodul1.cppのためのように見えるように、本当のを含めます物

#include "modul1.h" 
#include "easylogger.h" 

Modul1::Modul1(std::string name):log(new easylogger::Logger(name)) 
{ 
    //ctor 
    //std::ofstream *f = new std::ofstream(name.c_str(), std::ios_base::app); 
    //log->Stream(*f); 
    //log->Level(easylogger::LEVEL_DEBUG); 
    //LOG_DEBUG(*log, "ctor ende!"); 
} 

幸運!

+0

良い解決策。ありがとう。 – Burkhard

3

あなたの翻訳単位の両方で「easylogger-impl.h」が挙げられます。 easylogger-impl.hには関数定義があります。したがって、複数の関数定義があります。

1つの定義ルールには、オブジェクトまたは関数の定義が1つだけ必要であることが記載されています。

easylogger-impl関数をすべてinlineとマークするか、1つの翻訳単位にしか表示されないようにして、この問題を解決できます。

+2

[OK]をクリックすると、 "faulty"機能がインラインで動作しますが、他の人からコードを変更する必要があります。 easylogger-impl関数が1つの翻訳単位でしか表示されないようにするにはどうすればよいですか? – Burkhard

関連する問題