2012-11-07 20 views
3

訪問作爲方法類的成員數據/函數的正確方法是什麼?似乎有3種手段:使用THIS或成員範圍從對象本身訪問成員

class test{ 
    private: 
     int variable; 
    public: 
     void setVariable(int value) { 
      variable = value;  // method 1, using the variable name directly 
      this->variable = value; // method 2, via pointer dereference of 'this' 
      test::variable = value; // method 3, via scope operator 
     } 
}; 

他們似乎都工作盡我所知。它們是否相同?除了風格/一致性之外,是否有理由使用另一個?

回答

3

除了風格和一致性,你提到,有時你必須使用特定的語法歧義。

「方法2」可用於消除局部變量和類成員之間的歧義。

「方法3」可用於在類層次結構的不同位置爲具有相同名稱的字段之間消歧。

-1

使用方法1

variable = value; 

節省你買一個新的鍵盤,這樣頻繁!

(說到這裏我應該停止涌流咖啡超過我的!)

1
  • 方法1:這是常見的方式是做。
  • 方法2:這是最好的和最一致的方式來做到這一點。它使得閱讀和理解發生的事情變得非常清楚。
  • 方法3:我從來沒有在真實世界的代碼中看到過。

作爲附帶說明:當使用方法1如果存在與該函數的參數將在成員變量可以使用該函數的參數和成員變量命名衝突。

如果我們有:

void setVariable(int variable) { 
    variable = variable;  // method 1, this does not change the member variable. 
    this->variable = variable; // method 2, via pointer dereference of 'this' 
    test::variable = variable; // method 3, via scope operator 
} 
+0

呃?函數的參數是'value' –

+0

@EdHeal你是對的。但是,如果該參數的名稱已更改爲與成員變量相同的名稱,則這只是一個示例。這是罕見的,但可能的。 – andre

+0

但這不在OP中。無論如何,當爲ESA工作時,我們用'm_'爲前綴成員變量。問題已解決 –

0

這個指針經常用於比較一個類的重載操作符。一個它的用途可以是如果在功能傳遞的參數是相同的對象本身,例如:

class CDummy { 
    public: 
    int isitme (CDummy& param); 
}; 

int CDummy::isitme (CDummy& param) 
{ 
    if (&param == this) return true; 
    else return false; 
} 

也用於返回一個指向對象本身

ClassEx ClassEx::Func(//params) 
{ 
    //code 
    return *this; 
} 

至於正常比較,value而不是this->value會更有效使用,使用this->是不明確的,除非你正在檢查值。

1

對於對象內部的代碼,它通常沒有區別,所以通常只使用variable = value;並且完成它。

有時一個模板,你可以運行到這裏只是用變量名稱本身的情況是不明確的,並且this->variable刪除了歧義 - 但這是不夠罕見的,我肯定會經常不使用this->everything只是因爲它在一段時間內可能有用。

0

性能沒有差異。 ::用於避免含糊不清,例如,當您有一個具有相同名稱的本地變量的字段,或者在派生類中聲明具有相同字段名稱的字段的基類時。支持->是因爲this的類型是一個指向對象的指針,所以編譯器必須接受this->something,這也可以用來避免含糊不清或者讓代碼更清晰。

3

一般來說,這並不重要,所以更簡單的選項member = value;是首選。在某些情況下,局部變量可能不明確,您可以使用前綴進行限定,但更好的方法是完全避免混淆。

然而,有一些角落的情況下,它很重要。當使用虛擬功能的處理,使用合格的名稱(type::member禁用運行調度,並確保在type水平最終置換器被稱爲:

struct base { 
    virtual int f() { return 1; } 
}; 
struct derived : base { 
    virtual int f() { return 2; } 
    void g() { 
     std::cout << f() << "\n"; 
     std::cout << derived::f() << "\n"; 
    } 
}; 
struct mostderived : derived { 
    virtual int f() { return 3; } 
}; 
int main() { 
    mostderived d; 
    d.g();   // 3 2 
} 

當模板類和繼承處理,查找在執行兩個階段。在第一階段,必須解決非依賴名稱。非限定名稱是非依賴名稱,因此在某些情況下,您需要符合this->type::,上述區別仍適用。額外的資格用於使依賴名稱:

template <typename T> 
struct derived : T { 
    void g() { 
     // std::cout << f() << "\n"; // Error, cannot resolve f() [*] 
     this->f();      // Ok, pick final overrider at runtime 
     derived::f();     // Ok, pick overrider here: base::f() 
    } 
}; 
struct base { 
    virtual int f() { return 1; } 
}; 
struct mostderived : derived<base> { 
    virtual int f() { return 3; } 
}; 
int main() { 
    mostderived d; 
    d.g();        // 3, 1 
} 
0

,並添加上述答案: 一些代碼風格喜歡用固定的前綴,像_m識別成員變量。使用「方法2」是在代碼中實現這種清晰度的另一種方法(和更好的方法)。

Prefering this->value超過value也有點像使用std::cin代替cinusing namespace std