私はここで静的関数に関するいくつかの投稿を読みましたが、それでも実装に問題があります。
最短経路を見つけるためのダイクストラのアルゴリズムのハードコードされた例を書いています。
Alg.hで宣言:
static void dijkstra();
Alg.cppで定義:
static void Alg::dijkstra() {
//Create Map
Initialize();
//Loop to pass through grid multiple times
for(int i=0; i<5; i++)
{
current=1;
while(current!=6)
{
//Iterate through and update distances/predecessors
//For loop to go through columns, while current iterates rows
for(int j=1; j<7; j++)
{
//Check if distance from current to this node is less than
//distance already stored in d[j] + weight of Edge
if(distanceArray[current][j]+d[current]<d[j])
{
//Update distance
d[j] = distanceArray[current][j]+d[current];
//Update predecessor
p[j] = current;
}
}
//Go to next row in distanceArray[][]
current++;
} //End while
} //End for
output();
} //End Dijkstras
Mainからオブジェクトなしで関数を呼び出したいです。 Main.cppにこのコードをすべて置いたとき、完全に機能しました。それを別々のファイルに分割すると、エラーMain.cpp:15: error: ‘dijkstra’ was not declared in this scope
が発生しました。SEを検索するときに出会った投稿は、これを行うには、そのメソッドを静的にする必要があるという印象を与えましたが、まだ運がありません。
私は何を間違えていますか?
Main.cpp:
#include <iostream>
#include "Alg.h"
int main() {
dijkstra();
return 0;
}
編集:完全なヘッダーファイル、Alg.hを追加しました:
#ifndef Alg_
#define Alg_
#include <iostream>
#include <stack>
using namespace std;
class Alg
{
public:
void tracePath(int x);
void output();
void printArray();
void Initialize();
static void dijkstra();
int current, mindex;
int distanceArray[7][7]; //2D array to hold the distances from each point to all others
int d[6]; //Single distance array from source to points
int p[6]; //Array to keep predecessors
int copyD[6]; //Copy of d[] used for sorting purposes in tracePath()
int order[6]; //Contains the order of the nodes path lengths in ascending order
}; //End alg class
#endif
元のオールインワン作業Main.cppファイル: http://Pastebin.com/67u9hGsL
次のように呼び出す必要があります。
_Alg::dijkstra();
_
制限
new class()
を介してオブジェクトをインスタンス化できます。例えば。ファクトリー関数。すべての静的メンバーを持つクラスを持つ代わりに、名前空間を使用できます。
Alg.h:
namespace Alg
{
void dijkstra();
}
およびAlg.cppで
namespace Alg
{
void dijkstra()
{
// ... your code
}
}
main.cppで
#include "Alg.h"
int argc, char **argv)
{
Alg::dijkstra();
return 1;
}
関数は静的であると確信していますか?
機能だけが必要なように見えますか?ヘッダーファイル内:
#ifndef DIJKSTRA_H
#define DIJKSTRA_H
void dijkstra();
#endif
あなたのcppファイルで
void dijkstra() {
/* do something */
}
あなたのメインファイルで:
#include "yourcppfile.h"
int main(int argc, char **argv) {
dijkstra();
}
静的関数が本当に必要な場合は、ネストされたクラスに配置する必要があります。
class Alg {
public:
static void dijkstra();
/* some other class related stuff */
}
cppファイルのどこかの実装
void Alg::dijkstra() {
/* your code here */
}
そして、メインが存在するcppファイル内
#include "your header file.h"
int main(int argc, char **argv) {
Alg::dijkstra();
}
私の記憶が正しければ、「静的」関数は実装されているモジュールに限定されます。したがって、「静的」は、別のモジュールで関数を使用することを防ぎます。
クラスArg
の完全な宣言ができたので、シングルトンデザインパターンが有用であると思われます。
関数をオブジェクト関数ではなくクラス関数にするためにクラスで使用される 'static'キーワードと、ローカル関数の 'static'キーワードを混同しています。
Alg.cppの最初の行とヘッダーファイルからstatic
を削除します。これにより、Alg.oはmain
が参照でき、リンカーがリンクできるグローバルシンボルを含むことができます。
@egurで述べたように、Alg::dijkstra()
を呼び出す必要があります。
この後もエラーが発生する場合があります。 Alg ::の使用方法は、「クラス」定義というよりはnamespace
に似ています。
ヘッダーファイルでAlg.h
:
#ifndef __ALG_H__
#define __ALG_H__
namespace Alg {
void dijkstra();
}
#endif
インクルードガードは、複数のcppファイルにヘッダーを含める場合に必要です。関数を名前空間Alg
に入れたいと思われますよね?
Alg.cppで:
#include "Alg.h"
void Alg::dijkstra() { /* your implementation here */ }
次に、main.cppで、完全な名前空間の資格で呼び出します。
#include "Alg.h"
int main() {
Alg::dijkstra();
}
コードを複数のファイルに分散したいだけの場合、関数をstatic
と宣言する必要がある理由がわかりません。
ここのキーは‘dijkstra’ was not declared in this scope
エラー。
オールインワンのソースファイルを取得し、main
関数を削除します。これを含む新しいソースファイルを作成します。
void dijkstra();
void output();
int main(int argc, char *argv[]) {
dijkstra();
output();
return 0;
}
main
のないオールインワンcppと上記のこのファイルは一緒にコンパイルされ、1つのソースで以前と同じ結果が得られるはずです。 duplicate symbol _main
アルゴリズムファイルからメインを削除するのを忘れた場合のエラー。
static
は必要ありません。
ここでの私の答えは、ヘッダーファイルの適切な実践に触れていません。つまり、これらの関数宣言を.h
ファイル。ただし、コンパイル時エラーは解決します。
プログラムのコンテキスト(言語的な意味で)がキーワードの意味を変えることができるC++のいくつかの機構を通してあなたを助ける良い本を見つけたいかもしれません。これは戸惑う可能性があり、C++と同じくらいカラフルな歴史を持つ言語にとってまさにそれであることが証明されています。本の提案については こちら をご覧ください。