(原創) 是否該用this這個keyword? (C/C++)

一般人很少會用this這個keyword,可是為什麼在我的程式碼中會使用this呢?

大部分會使用到this,是想將整個物件當參數傳給其他function,如

foo.func1(*this)


但我常常在member function內使用this,有幾個理由

1.利用visual studio的intellisense

打了this->後,intellisense會列出所有可用的data member和member function,你只要挑就好了,不用去強記,也可避免打錯。

2.this能清楚的表示class自己的member function

如以下寫法

void Foo::func1() {
  func2();
}


請問func2到底是個global function?還是某個namespace下的function?還是class自己的member function?若用以下寫法

void Foo::func1() {
  
this->func2();
}


就能明確的表示是class自己的member function,非常清楚。

3.this能清楚的表示class自己的data member

如以下寫法

 1#include <iostream>
 2
 3using namespace std;
 4
 5class Foo {
 6public:
 7  int i;
 8public:
 9  void func1(int i) {
10    i = i;
11  }

12}
;
13
14int main() {
15  Foo foo;
16  foo.func1(5);
17  
18  cout << foo.i << endl;
19}


compile可過,但執行結果是錯的,因為C++已經遇到第10行

= i


已經傻眼了,到底哪個是variable,哪個是data member?

若改成

 1#include <iostream>
 2
 3using namespace std;
 4
 5class Foo {
 6public:
 7  int i;
 8public:
 9  void func1(int i) {
10    this->= i;
11  }

12}
;
13
14int main() {
15  Foo foo;
16  foo.func1(5);
17  
18  cout << foo.i << endl;
19}

20


則程式就對了,10行的

this->= i;


this->i為data member,i為variable。

所以只要是data member,我一律加上this,這樣就可明確的分辨data member和variable。

4.在class template中使用this避免錯誤

在使用class template且使用繼承機制時,如以下程式

 1/* 
 2(C) OOMusou 2007 http://oomusou.cnblogs.com
 3
 4Filename    : TemplateThis.cpp
 5Compiler    : Visual C++ 8.0 / BCB 6.0 / gcc 3.4.2 / ISO C++
 6Description : Demo how to use this in class template
 7Release     : 01/04/2007 1.0
 8*/

 9
10#include <iostream>
11
12using namespace std;
13
14void exit() {
15  cout << "Global exit()" << endl;
16}

17
18template <typename T>
19class Base {
20public:
21  virtual void exit() 
22    cout << "Base's exit()" << endl;
23    
24  }

25}
;
26
27template <typename T>
28class Derived : public Base<T> {
29public:
30  void exit() {
31    cout << "Derived's exit()" << endl;
32  }

33  
34  void foo() {
35    // ??which exit()?
36    exit();
37    this->exit();
38    Base<T>::exit();
39    ::exit();
40  }

41}
;
42
43int main() {
44  Derived<int> obj;
45  obj.foo();
46}


執行結果

Derived's exit()
Derived's exit()
Base's exit()
Global exit()


請問36行的exit()是哪一個exit()?在VC 8.0,選擇的是Derived<T>::exit(),不過在不同compiler並非如此,在『C++ Template全覽』p.45提到

本例在foo()內決議(resolving)"exit"符號時,定義於Base的exit()會被編譯器忽略。因此,你要嘛獲得一個編譯錯誤,要嘛就是喚起一個外部的exit()。


對於這種情形,『C++ Template全覽』p.45的建議是

使用與template相關的符號時,建議總以this->或Base<T>::進行修飾。為避免任何不確定性,可考慮在templates內對所有成員存取動作(member access)進行以上修飾。


37行

this->exit();


明確的呼叫Derived<T>::exit();

38行

Base<T>::exit();


明確的呼叫Base<T>::exit();

39行

::exit();


明確的呼叫Global function。

Conclusion
this的習慣,是我從C#帶來的,因為C++也適用,所以就繼續用了,這是我個人的小習慣,雖然讓程式到處多了this這個沒用的東西,卻讓程式碼更清楚。

Reference
C++ Templates全覽 p.45,侯捷 / 榮耀 / 姜宏 譯, 碁峰

posted on 2007-03-31 10:22  真 OO无双  阅读(987)  评论(0编辑  收藏  举报

导航