0

DragonFireSDK でアプリを作成しており、数千行のアプリを .cpp および .h ファイルで整理したい

何かをしようとすると、大量のエラーが発生します

したがって、私のapp.cpp(メイン、必須のもの)は次のようになります

コード:

#include "DragonFireSDK.h"

#include "SaveData.h"
#include "Structures.h"
#include "Definitions.h"
#include "Variables.h"
#include "SaveData.h"

#include <time.h>
#include <stdio.h>
#include <stdlib.h>
#include <math.h>

#include "Functions.cpp"
#include "AppMain.cpp"
#include "AppExit.cpp"
#include "OnTimer.cpp"

#include "SaveData.h" から #include "Variables.h" までのコードはすべて次のようになります。

#ifndef _HeaderName
#define _HeaderName
//STUFF HERE LIKE
#define player1 0
#define player2 1
//OR
typedef struct _number {
    int view;
    int number;
    bool able;
    int opacity;
};_number number[4];
//OR
int whoseturn;

int bet[5];
bool reachedmax[5];

int playerimg[5];
#endif

今、私はすでに何か間違ったことをしているかもしれませんが、ここにいくつかあります...私のAppMain.cpp、OnTimer.cppなどは次のようになります(AppMain()なども必要な機能です) コード:

#include "DragonFireSDK.h"
#include <time.h>
#include <stdio.h>
#include <stdlib.h>
#include <math.h>

#include "Definitions.h"
#include "Structures.h"
#include "Variables.h"
#include "SaveData.h"

#include "Functions.cpp"

void AppMain() {
//STUFF HERE
};

ここが問題だと思います... Functions.cpp コード:

#include "DragonFireSDK.h"

#include <time.h>
#include <stdio.h>
#include <stdlib.h>
#include <math.h>

#include "SaveData.h"
#include "Structures.h"
#include "Definitions.h"
#include "Variables.h"
//SOME FUNCTIONS
void   SavePlayerMoney();
void   SetInfo            (int idnum, bool actuallyset = false);
void   SwitchButton       (int idnum, bool makeactive=true);
void   DisableButton      (int idnum);
double round              (double number);

void SavePlayerMoney() {
    //...
}
void   SetInfo(int idnum, bool actuallyset) {
      //...
}
void   SwitchButton(int idnum, bool makeactive) {
      //...
}
void   DisableButton(int idnum){
      //...
}

すべてのものを修正したかどうかを考えた後、エラーが発生しました...コード:

1>AppMain.obj : error LNK2005: "void __cdecl SwitchButton(int,bool)" (?SwitchButton@@YAXH_N@Z) already defined in App.obj
1>AppMain.obj : error LNK2005: "double __cdecl round(double)" (?round@@YANN@Z) already defined in App.obj
1>AppMain.obj : error LNK2005: "void __cdecl SetInfo(int,bool)" (?SetInfo@@YAXH_N@Z) already defined in App.obj
1>AppMain.obj : error LNK2005: "int __cdecl Digits(int)" (?Digits@@YAHH@Z) already defined in App.obj

どんな助けでも大歓迎です!

4

4 に答える 4

2

関数が複数回定義されているため、リンカーは不平を言います。関数は 1 つの翻訳単位 (cpp ファイル、コンパイル後は obj ファイルになります) でのみ定義できます - 宣言されている場合を除きますinline

他のユニットにインクルードしているFunctions.cppため、からの関数定義がFunction.cppそれらに重複し、リンカの問題が発生します。

解決策は、関数を宣言することですinline。または、さらに良いのは、それらをヘッダーで宣言Functions.hし (つまり)、 で定義することですFunctions.cpp。これらの関数のユーザーは#include Functions.h、実装を知らなくても、これらの関数にアクセスできます。

関数を宣言するint foo();には、次のようにします。実際に定義するには、次のようにします。int foo() { your code goes here}.

于 2011-04-06T23:05:49.323 に答える
2

誰もがこれに非常によく答えたと思うので、大きなプロジェクトでの私の C++ 哲学を紹介します。これは、役に立つと思われる情報だと思われるからです。

関数の宣言と実装は常に分離してください。 それはあなたの人生をかなり楽にしてくれます。.h ファイルで関数プロトタイプを宣言してから、実装を .cpp ファイルに記述します。

例えば:

// mystuff.h
#ifndef MYSTUFF_H
#define MYSTUFF_H

int myFunction(int value, char letter);

#endif

そして私の .cpp ファイルで:

// mystuff.cpp

#include "mystuff.h"

int myFunction(int value, char letter) {
    // insert implementation here
}

なぜこれを行うのですか?大きな理由の 1 つは、コードが機能しない場合 (表向きはそうであるように、プログラマーにとって避けられない現実です)、コードの構造を変更せずに、.cpp ファイルを別の実装に置き換えることができることです。それだけでなく、宣言と実装を分離することに依存するさまざまなトリックを発見できるので、作業が大幅に楽になります。要するに、それをしてください。

可能な限りカプセル化を試みます。 大きなプロジェクトを実行している場合 (これは、遭遇するほとんどの大規模プロジェクトに当てはまることに気付くでしょう)、同様の関数や変数などをカプセル化すると、かなりの時間とエネルギーを節約できます。ゲームをプレイするプログラムを作成しているようですね。各プレイヤーを Player または Human クラスにカプセル化し、それぞれにクラス固有の機能を持たせることを考えたことはありますか? あなたが私のような C++ または Java ジャンキーである場合、オブジェクト指向アプローチが 100 回中 99 回最も効果的なアプローチであることがわかります (状況の 1% は通常、実際には適合しないヘルパー関数がある場合です)。定義した任意のオブジェクトで)。

また、カプセル化により、オブジェクト指向設計の他の 2 つの基本原則であるポリモーフィズムと継承を利用できます。たとえば、Player クラスを定義し、ゲームにコンピューター プレーヤーと人間のプレーヤーが含まれる場合、Player の基本機能を継承し、Player の各機能を別の方法 (つまり、makeMove 関数がある場合、人間とコンピューターでは異なる実装が必要になります。したがって、継承によって作業が大幅に簡素化されます)。OO 設計には明らかに多くの魅力的な性質がありますが、私があなたのコードから収集したものについては、これらのものから最も恩恵を受けると思います。

明らかに、これは私自身の哲学であり、あなたに強制したいものではありません. しかし、コードの記述方法を改善したり、エラーの長いリストを回避したりするために、私の簡潔なとりとめのないヒントからいくつかの役立つヒントを取得していただければ幸いです。頑張ってください!

于 2011-04-06T23:25:34.663 に答える
1

関数宣言をヘッダー ファイルに移動します。たとえば、Functions.h には以下が含まれている必要があります。

#ifndef FUNCTIONS_H
#define FUNCTIONS_H

//SOME FUNCTIONS
void   SavePlayerMoney();
void   SetInfo            (int idnum, bool actuallyset = false);
void   SwitchButton       (int idnum, bool makeactive=true);
void   DisableButton      (int idnum);
double round              (double number);

#endif

次に、Functions.cpp は、それらの宣言の代わりに Functions.h を含めることができます。一部のヘッダー ファイルには、適切なタイプを取得するために他のヘッダー ファイルを含める必要がある場合があります。

最後に、決して#include*.cpp ファイルではありません。

于 2011-04-06T23:07:41.427 に答える