3

dll にリンクする必要がある単純なロガー (サード パーティのライブラリを使用しない) を生成する必要があります。したがって、彼のクラスメソッドの一部がテンプレートであるクラスを生成しました。コードは正常にコンパイルされますが、リンカーエラーが発生します。MS VS 2008 と gcc-4 でコンパイルしています。コードは次のとおりです。

Log.h クラス:

class MiniLogger
{
private:
   std::ofstream mOutPutFile;
protected:
   void write (std::string const& text);
public:
   ~MiniLogger();
   MiniLogger( std::string const& lName) throw(FileError);
   static MiniLogger* getInstance(std::string const & fName);
   static void destoryInstance(MiniLogger*);

  template<class T>
  MiniLogger& operator<<(T & data);
  MiniLogger& operator<<(std::ostream& (*func)(std::ostream&) );

};


MiniLogger& MiniLogger::operator<< (std::ostream& (*func)(std::ostream&))
{

   //mOutPutFile << out;
   return *this;
}
template<class T>
MiniLogger& MiniLogger::operator<< (T  & data)
{
 //Just try with out calling other method
// write(data);
   return *this;
}

主に、オブジェクトをインスタンス化して使用します:

#include "log.h"

int main()
{


    MiniLogger &a=*(MiniLogger::getInstance("text.txt"));

    a << "text" << std::endl;


return 0;
}

私は得る

@ubu11-10-64b-01:~/cplus/template$ g++ main.cpp log.cpp
/tmp/cccMdSBI.o: In function `MiniLogger::operator<<(std::basic_ostream<char, std::char_traits<char> >& (*)(std::basic_ostream<char, std::char_traits<char> >&))':
log.cpp:(.text+0x0): multiple definition of `MiniLogger::operator<<(std::basic_ostream<char, std::char_traits<char> >& (*)(std::basic_ostream<char, std::char_traits<char> >&))'
/tmp/ccj3dfhR.o:main.cpp:(.text+0x0): first defined here
4

1 に答える 1

4

ヘッダー ファイルで関数を定義しました。そのヘッダー ファイルは複数の翻訳単位 (つまり、main.cpp と log.cpp) に含まれているため、関数を複数定義しています。( 1 つの定義規則を参照してください。)

関数inlineを宣言してヘッダー ファイルで定義するか、ヘッダー ファイルで宣言してextern1 つのソース ファイルで定義します。

問題の関数は次のとおりMiniLogger& MiniLogger::operator<< (std::ostream& (*func)(std::ostream&))です。

解決策 1:

// Log.h
inline
MiniLogger& MiniLogger::operator<< (std::ostream& (*func)(std::ostream&))
{
 //mOutPutFile << out;
 return *this;
}

解決策 2:

// Log.h
extern
MiniLogger& MiniLogger::operator<< (std::ostream& (*func)(std::ostream&));

// Log.cpp
MiniLogger& MiniLogger::operator<< (std::ostream& (*func)(std::ostream&))
{
 //mOutPutFile << out;
 return *this;

}


補足: ヘッダー ファイル内の次のエンティティ はtemplate<class T> MiniLogger& MiniLogger::operator<< (T & data)関数ではなく、関数テンプレートであることを認識してください。別のアドバイスが適用されます。経験則として、ヘッダー ファイルで関数テンプレートを定義する必要がありますが、ヘッダー ファイルで関数を定義しないでください。(この経験則には例外があります。)

于 2012-04-24T15:38:26.550 に答える