web-dev-qa-db-ja.com

C ++の静的関数

私はここで静的関数に関するいくつかの投稿を読みましたが、それでも実装に問題があります。

最短経路を見つけるためのダイクストラのアルゴリズムのハードコードされた例を書いています。

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

19
Ladybro

次のように呼び出す必要があります。

_Alg::dijkstra();
_

制限

  • 静的ではない他のクラス関数を呼び出すことはできません。
  • 非静的クラスデータメンバーにアクセスできません。
  • コンストラクターがprivate/protectedの場合、new class()を介してオブジェクトをインスタンス化できます。例えば。ファクトリー関数。
25
egur

すべての静的メンバーを持つクラスを持つ代わりに、名前空間を使用できます。

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;
}
8
user3053099

関数は静的であると確信していますか?

機能だけが必要なように見えますか?ヘッダーファイル内:

#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();
}
6
Alex

私の記憶が正しければ、「静的」関数は実装されているモジュールに限定されます。したがって、「静的」は、別のモジュールで関数を使用することを防ぎます。

1
VladimirM

クラスArgの完全な宣言ができたので、シングルトンデザインパターンが有用であると思われます。

http://en.wikipedia.org/wiki/Singleton_pattern

0
blackbird

関数をオブジェクト関数ではなくクラス関数にするためにクラスで使用される 'static'キーワードと、ローカル関数の 'static'キーワードを混同しています。

Alg.cppの最初の行とヘッダーファイルからstaticを削除します。これにより、Alg.oはmainが参照でき、リンカーがリンクできるグローバルシンボルを含むことができます。

@egurで述べたように、Alg::dijkstra()を呼び出す必要があります。

この後もエラーが発生する場合があります。 Alg ::の使用方法は、「クラス」定義というよりはnamespaceに似ています。

0
KeithSmith

ヘッダーファイルで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と宣言する必要がある理由がわかりません。

0
blackbird

ここのキーは‘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++と同じくらいカラフルな歴史を持つ言語にとってまさにそれであることが証明されています。本の提案については こちら をご覧ください。

0
Prashant Kumar