2017-01-12 100 views
2

如果我有一個虛函數,沒有free函數的一類,是有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

在您發佈的例子中,有兩種語法之間沒有什麼區別。它們完全相同。

有兩種情況是有區別的。一個是如果你有一個模板類繼承自一個依賴於模板參數的類型。例如:從類型Base<T>,它依賴於模板參數

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

在此,由於Derived<T>繼承,名稱查找是在兩個步驟的過程來完成。如果使用非限定語法調用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'中有一個本地聲明的函數{ion |或}(在這種情況下它將被命名爲'doSomething')會以相同的名稱來映射該方法。 – HolyBlackCat

+1

@HolyBlackCat你是對的。讓我去更新這個。 – templatetypedef

3

一般來說沒有區別,因爲標準要求以A()的形式調用成員函數以等同於(*this).A()。那裏有一個區別是一些例子:

  1. 如果存在的A一個塊範圍聲明,然後將A()調用函數聲明,而this->A()總是會調用成員函數。見http://coliru.stacked-crooked.com/a/ea49916562bd4371
  2. 如果A是從屬基類然後試圖調用它作爲A()將失敗的成員;需要this->A()才能推遲名稱查找,直到實例化時間。
0

關於Non-static member functions指出存在的模板定義的上下文中,差Cppreference:

在X,任何 ID-表達E的非靜態成員函數的主體(例如標識符)解析爲一個非類型 非靜態的X或基類X的成員,被變換爲 成員訪問表達(*此).E(除非它是已經是 構件訪問表達式的一部分)。這在模板定義 上下文中不會發生,所以名稱可能必須以此 - >明確爲 成爲相關前綴。

因此,在您的示例中,它沒有區別,但在其他情況下,例如,當定義模板時,它可能會。

相關問題