18

この関数はグローバルであり、ヘッダーファイルで定義されています(一時的にそこに保持したい)。

ヘッダーファイルは、インライン関数を持つ特定のクラスも構成し、それらの関数の1つがこのグローバル関数を呼び出します。

ソースファイルには、問題のグローバル関数のオカレンスは含まれていません。

エラーの原因に関するヒントはありますか?

興味があればコードを投稿できます。

mainwindow.o: In function `tileForCoordinate(double, double, int)':
mainwindow.cpp:(.text+0x310): multiple definition of `tileForCoordinate(double, double, int)'
main.o:main.cpp:(.text+0xd0): first defined here
moc_mainwindow.o: In function `qHash(QPoint const&)':
moc_mainwindow.cpp:(.text+0x0): multiple definition of `qHash(QPoint const&)'
main.o:main.cpp:(.text+0x0): first defined here
moc_mainwindow.o: In function `tileForCoordinate(double, double, int)':
moc_mainwindow.cpp:(.text+0x150): multiple definition of `tileForCoordinate(double, double, int)'
main.o:main.cpp:(.text+0xd0): first defined here
collect2: ld returned 1 exit status
make: *** [SimpleRouting] Error 1
4

5 に答える 5

33

次のようにマークしますinline

 inline void globalfunc() { 
 }

そうすることは、厳密にはグローバルではなくなることを意味しますが、ヘッダーを使用する各変換ユニットでコピーを取得しますが、リンカーはこれに反対しません。

于 2011-05-21T09:31:18.783 に答える
10

ヘッダーに関数を配置すると、そのヘッダーを含むc / cppファイルごとに関数が生成され、重複が発生します。インライン化すると役立ちます。

編集、説明

#ifndef、#define ... #endif構文としてのヘッダーガードは、多くの場合、単一のcppファイルに二重かつ再帰的に含まれるのを防ぐためにのみ呼び出されます。これは、ソースファイルにヘッダーAとBが含まれ、BにもAが含まれている場合に関係します。AにBも含まれている場合、再帰的な包含が発生します。

複数の.cppファイルがあるために問題が発生します。1つのcppのコンパイル中、コンパイラは他のcppファイルの存在を認識しません。

#include、#ifdef、およびfriendsはプリプロセッサディレクティブであることに注意してください。前処理は、コンパイル前にソースファイルで行われます(多くの場合、コンパイルプロセスの一部と見なされ、実行されます)。プリプロセッサは基本的にテキストプロセッサです。たとえば、#includeはテキストでヘッダーファイルの内容に置き換えられます。falseと評価される#ifdefの内容は、コードから削除されます。実際のコンパイラは、cppと参照されるすべてのインクルードファイルで構成される単一の大きなファイルを取得し、それをオブジェクトファイルに変換します。

于 2011-05-21T09:33:14.453 に答える
8

2つのオプションがあります:

nbtで説明されているように、インラインとして、または静的としてマークします。

inlineは、ソースからグローバル関数の実装を取得し、関数が呼び出される場所にコピーします。

inline void global_func ()
{
...
}

staticは、コードを新しいオブジェクトファイルにコピーせず、元のオブジェクトファイルでのみ参照するようにリンカーに指示します。

static void global_func ()
{
...
}
于 2013-11-07T02:45:05.910 に答える
3

ヘッダーファイルで定義されたグローバル関数の場合、名前のない名前空間内でそれを宣言することも機能するはずです。DeitelによるC++のプログラミング方法によると、C ++では、静的な名前空間よりも名前のない名前空間の方が適しています。

だからあなたはこれを行うことができます:

// \file GlobalFunctions.h

namespace  // an un-named namespace
{

void GlobalFunctionOne() {...implementation...}

} // end un named namespace
于 2013-12-19T10:45:07.293 に答える
-3
#ifndef SOMESTRING
#define SOMESTRING
... header code
#endif

ヘッダーのコードは、最初にのみ含まれます。

于 2011-05-21T09:35:10.867 に答える