2

別のメンバー関数を呼び出す次の 4 つのスタイルの違いは何ですか?

1 つの方法が好ましいという利点はありますか?

void Object::trigger() {
  (*this).triggerinner(10);
  this->triggerinner(10);
  triggerinner(10);
  Object::triggerinner(10);
}

void Object::triggerinner(int x) {
  std::cout << "trigger" << std::endl;
}
4

6 に答える 6

4

最初の 3 つは、非テンプレート コードでは基本的に同じです。テンプレート メンバー関数では、最初の 2 つは名前のルックアップを依存させます (したがって、コンパイラは依存する基本クラスで名前を見つけることができます)。一般に、シンプルなほど良いため、ほとんどの人は 3 番目の形式を好みます。ただし、依存ルックアップが必要な場合は 2 番目を使用します。

4 番目の形式は、仮想解決をブロックします。(実際には、上記と同じ 3 つの形式、つまり this->Object::triggerinner(10)などがあります。) 強制的に解決したい場合に使用します。呼び出される関数は Object、 の基底クラスまたはその中にありますObjectが、派生クラスには決してありません。 、関数が仮想であっても。これは、派生クラスで最もよく使用され、追加の作業を行う前 (または後) に基本クラスの実装を呼び出します。

void
Derived::func()
{
    Base::func();
    //  Additional work here...
}

メンバー関数の外では、オブジェクトがない場合に静的メンバー関数を呼び出すためにも使用できます。

于 2013-10-23T08:10:31.237 に答える
1

最初の 2 つはまったく同じです。定義により、(*p).thingおよびp->thingは任意のポインターと同等です。

3 番目は、この状況では同等です。ただし、メンバー関数の名前がローカル宣言によって隠されている場合は、別の意味になる可能性があります。このフォームが関数を見つけられない状況 (関数が基本クラスのメンバーであり、テンプレートが関係している場合) もあります。その場合、他のいずれかを使用する必要があります。

関数が仮想でない場合、4 番目は同等です。仮想の場合、最終的なオーバーライドではなく、このクラスで使用可能なオーバーライドへの非仮想呼び出しが強制されます。

于 2013-10-23T08:07:53.070 に答える
-1

あなたのコンパイラがファンキーなことをしない限り、違いはありません。関数内の行によって生成されたアセンブリ言語を読んでみて、違いがあるかどうか、または同じ命令ブロックが何度も生成されているかどうかを確認してください。

あなたの個人的な好みに帰着する「最高」または「最も人気のある」ものについては、または会社で働いているときに、特定のコーディング標準を強制して、毎回何かを行うときに特定の方法で書くことを強制する場合があります.

于 2013-10-23T08:06:41.793 に答える