2009-05-08 7 views
4

は、私が持っていると言う:私はDoStuffを呼び出したい機能を持っている上C++オブジェクトへのポインタを指定すると、静的メンバー関数を呼び出すにはどうすればよいでしょうか?

class A { 
public: 
    static void DoStuff(); 

    // ... more methods here ... 
}; 

以降:

B::SomeFunction(A* a_ptr) { 

はそれを言った方が良いです:

a_ptr->DoStuff(); 
} 

または、次のさより良い私は、インスタンスのポインタ持っているにもかかわらず:

A::DoStuff() 
} 

これは純粋にスタイルの問題ですが、私は決定を下す前に情報に基づいた意見を出したいと思います。

+4

総計:しかし、C++には「メソッド」はありません。それは機能を持っています。 C++標準のどこにも、「メソッド」についての話はありません。メソッドは、C++で関数にマップする一般的なOOの用語です。 あなたの質問に関しては、純粋にスタイルのもの、彼らはどちらも同じことをします。 –

+0

固定されています。 –

+1

LOL、厄介なB *スタードにごめんね。 –

答えて

22

は、私はそれは、静的メソッドが呼び出されていることをより明確だとして、私は、「A :: DoStuff()」を好むと思います。

+0

私はアダムの例が本当に好きですが、私はこの主観的な質問のチェックを群衆が好きにします。 –

6

それは静的メンバ関数の呼び出しだと、コードを読んで誰にでもすぐに明らかですので、私は個人的にはA :: DoStuff()規則を好みます。

19

それは実際にはまったくそのオブジェクトを使用していないので、それは、ないオブジェクトを介して、その名前の静的メソッドを呼び出す方が良いでしょう。 Javaでは、同じ問題が存在します。 Javaで - あまりにも珍しいことではありません問題は以下の通りです:

Thread t = getSomeOtherThread(); 
t.sleep(1000); 

これは罰金コンパイルが、ほとんど常に誤りである - Thread.sleep()眠りに現在のスレッドを起こし静的メソッドである、ではないスレッドがあることコードが意味するように行動しました。私は:: DoStuff()が明確であることに同意し、それは私が自分自身を書きたいものだが

+0

良い点。 C++フレームワークでも同様のエラーが発生する可能性があると思います。 –

+1

APIにこれがある場合は、これがAPIの主要な「バグ」だと思います。おそらく、Javaには、これを行う必要のあるフリー関数の概念がないためです。しかし、これはC++では必須ではありません。関数がオブジェクト(private constructorなど)に特別なアクセス権を持つ場合、関数はメンバ関数でなければなりません。 –

3

は、私が「クラス名の変更を想定」でポインタを経由して行くための引数を見ることができます。クラスAがクラスBになると、クラス名を2つではなく1つの場所(ポインタ宣言)で更新するだけで済みます。

だけの思考...

+1

また、静的メソッドはいつかインスタンスメソッドに変更される可能性があります。私はそれが機会に起こるのを見ました。 –

+0

いずれかを変更すると、コンパイル時にエラーが発生します。名前の変更は検索と置換の単純な問題です(通常、「A」と「B」よりもわかりやすい名前でうまく動作します)。 –

0

は、一般的に私は(A :: DoStuffを行います)。代わりにa-> DoStuff();おそらくいつか私のいる関数は、リファクタリングのためにそのインスタンスポインタをもう持たないからです。しかし、それはあなたが眠りを失うべきではないトータルスタイルのものです。あなたは、インスタンスのポインタ経由の静的メソッドを呼び出してはならない理由に

1

Jon Skeet opened my eyes。彼の例は、Javaであるが、概念は、あまりにも、C++に適用されます。

Thread t = new Thread(...); 
t.start(); 
t.sleep(1000); // Which thread does it look like this will affect? 

私が最初に彼の答えを読んだとき、私はコメントしたよう:「私は[Jonの記事]を読むまで、私はを通じて静的メソッドを呼び出すことができることと考えられインスタンスがフィーチャを参照するようになりました。

つまり、インスタンスではなくクラス名を使用して静的メソッドを呼び出します。私の意見では、これはスタイルの問題以上のものです。誤解を招くバグの多いコードになる可能性があります。

+0

これは本当に人為的な例のようです。 Threadクラスにスリープメンバがある場合、そのメンバがそのスレッドだけに影響を与えない*場合、APIを書いた人を撃つべきです。 –

+0

もう1つの答えはこれも言及しています。だから、これはJavaの問題でなければなりません。しかし、Java APIの設計上の欠陥(フリー関数の欠如のため)は、C++での何かに対する良い議論ではありません。 –

+0

与えられた例は実際にはJavaでしたが、start()インスタンスメソッドと静的なsleep()メソッドを持つThreadクラスがあれば、C++でも多かれ少なかれ有効です。もちろん、 'new'を取り除かなければならないか、' t'をポインタにして 't.start()'を 't-> start()'に変更しなければなりません。インスタンスを介して静的メソッドを呼び出す点のほかにあります。 –

0

私は、人がオブジェクトを通してインスタンスメソッドを呼び出す構文を使用して静的メソッドを呼び出し、そのオブジェクトが実際には変数型のサブクラスである場合、人々はなぜそうではないのか疑問に思っていますサブクラスで同じ名前の静的メソッドを呼び出します。オブジェクトを介して呼び出すという事実は、それがオーバーライドできるインスタンスメソッドであると考え、オブジェクトの型を使用してランタイム動的ルックアップを何らかの形で実行します。

もちろん、オブジェクトは呼び出しで使用されることはありません。コンパイル時に変数の型だけがどのクラスの静的メソッドを決定するのに使用されます。だから、あなたがそこにオブジェクトを置くと、そうでないときに、それが使用されていると人々に思うようになるので、それは完全に誤解を招きます。だから私は、クラス名を使って静的メソッドを呼び出すほうが好きです。クラス型の変数を使って静的メソッドを呼び出すのと全く同じです。それは間違いのない余分な情報なしで何が起こっているかを正確に伝えます。

関連する問題