2017-01-12 3 views
2

this->func()func()this-> func()とfunc()の構文には微妙な違いがありますか?私はそこに、仮想関数なしの無料の機能を持つクラスを持っている場合

class Base { 
    virtual void A() { std::cout << "Base" << std::endl; }; 
    void B() { this->A(); }; 
    void C() { A(); }; 
}; 

class Derived : public Base { 
    virtual void A() { std::cout << "Derived" << std::endl; }; 
    void B2() { this->A(); }; 
    void C2() { A(); }; 
}; 

間のいずれかの違いがあり、メソッドB()C()の実行に違いはありますか? B2()C2()の方法はどうですか?

+0

完全に文章です。 – user4581301

答えて

7

投稿した例では、2つの構文に違いはありません。彼らは完全に同一です。

違いがある場合が2つあります。 1つは、テンプレート引数に依存する型から継承するテンプレートクラスがある場合です。例:ここでは

template <typename T> class Base { 
public: 
    void doSomething() const { 
     std::cout << "Do ALL the things!" << std::endl; 
    } 
}; 

template <typename T> class Derived: public Base<T> { 
public: 
    void doSomethingElse() const { 
     doSomething();  // Error! 
     this->doSomething(); // Okay 
    } 
}; 

は、テンプレート引数に依存タイプBase<T>、からDerived<T>継承しているので、名前の検索は、2段階のプロセスで行われます。修飾されていない構文を使用してdoSomethingを呼び出すと、コンパイラはBase<T>を調べてエラーを報告します。しかし、this->doSomething()と言うと、メンバー関数を呼び出していて、最終的にそれがBase<T>であるとわかっていることがわかります。

他のケースは、メンバー関数と同じ名前の関数内で宣言されたローカルオブジェクトがある場合です。たとえば:

class ThisIsSillyDontDoThisLikeSeriouslyDont { 
public: 
    void doSomething() const { 
     std::cout << "Do ALL the things!" << std::endl; 
    } 

    void weirdFunction() const { 
     auto doSomething = [] { 
      std::cout << "I'm afraid there's nothing to be done" << std::endl; 
     }; 

     doSomething();  // Calls the local function 
     this->doSomething(); // Calls the member function 
    } 
}; 

この第二のケースでは、私はそれを見たことがないほど稀であり、私はそれが本当に貧しいコーディングスタイルだと言うように遠くに行くと思います。

ただし、これらのまれなケースの他に、this->の有無にかかわらず、自分自身でメンバー関数を呼び出すことには違いがありません。

+0

別の場合があります: 'doSomethingElse'の中でローカルに宣言されたfunct {ion |または}(この場合は' doSomething'と名付けられます)が同じ名前のメソッドをシャドーすると、 – HolyBlackCat

+1

@HolyBlackCatあなたは絶対に正しいです。私はこれを更新しよう。 – templatetypedef

3

標準ではA()という形式のメンバー関数への呼び出しが(*this).A()と同等である必要があるため、違いはありません。差が存在するいくつかの例は、次のとおり

  1. Aのブロックスコープ宣言がある場合this->A()が常にメンバ関数を呼び出すのに対し、次いでA()は、宣言された関数を呼び出します。 http://coliru.stacked-crooked.com/a/ea49916562bd4371
  2. Aが従属基本クラスのメンバーである場合、A()と呼び出す試みは失敗します。 this->A()はインスタンス化時まで名前の参照を延期する必要があります。
0

テンプレート定義のコンテキストに差があることNon-static member functions状態に関するCppreference:X、任意 ID-式Eの非静的メンバ関数の本体内

(例えばXタイプの非スタティックメンバーまたはXの基本クラスの非タイプメンバー に解決されたメンバーアクセス式(* this).E(メンバーアクセス式の一部である場合を除き、これは メンバーアクセス式に変換されます。 )。これはテンプレート定義 コンテキストでは発生しません。したがって、名前に接頭辞としてthis->明示的に が必要になることがあります。

あなたの例では違いはありませんが、他の文脈ではテンプレートを定義するときに、それが可能性があります。

関連する問題