Fork me on GitHub
Showing posts with label reference. Show all posts
Showing posts with label reference. Show all posts

3/10/2013

[C++] Reference to Pointer

Recently, I met the usage of reference of the pointer as the function parameter. I don't know what the purpose of it, and google the answer for it.

The 1st ref. well explains the difference between "pass by pointer" and "pass by reference of the pointer". The key is the default parameter passing of C/C++ is "pass by value", evne the pointer.

The 2nd ref. shows the situation which the reference of pointer come to solve elegantly

Ref

  1. C++: Reference to Pointer

  2. why pointer to pointer is needed to allocate memory in function

6/17/2011

[Java] 淺談 call by value 和 call by reference

在 C++ 中, call-by-value 意味著把變數的值複製一份傳進函數;  而 call-by-reference 則意味著把變數的 alias (用 &var 或者指標) 傳進函數當中。

因此,在 C++ 中我是這麼理解的,在函數內部改變 call-by-value 傳入的參數並不會影響外部變數,因為傳進來的是它的複製品;  而改變 call-by-reference 傳入的參數則會影響到外部變數,因為 alias 是指向同一個 value 的。

基於這樣的理解,在學習 Java 的時候遇到「只有 call-by-value」這樣的觀念,便在讓我產生了疑惑:「要怎麼讓傳入函數的變數隨著函數內部對它操作而跟著變動」,也就是說 Java 要怎麼做到 call-by-reference 的語意呢?

後來發現,原本我以為 Java 的 call-by-value 和 C++ 的 call-by-value 有相同的立足點 (將物件複製一份丟進函數) 實際上是錯誤的。

原來,在 Java 當中,除了原生型別的變數,一般型別的變數其實不是直接 hold 物件本身,而是 hold 物件的 reference!

這點跟 C++ 就有一點出入了,在 C++ 中要用一個變數 hold 一個物件的 reference,只得明確用指標,像是 Dog* aDog = new Dog;  這樣一來,操作上也得用 -> 運算子,像是 aDog->setName('Lucky');  如果是用 Dog aDog; 那 aDog 這個變數就是指物件本身(傳進函數會被複製一份)。

Java 沒有指標的觀念 (全物件導向),除了原生型別,它的物件都需要用 new 建立 (跟 C++ 的 new 又不太一樣,C++ new 是用來動態配置記憶體用的)  如 Dog aDog = new Dog;  這裡的 aDog 並不是 Dog 型別的物件本身,而是物件的一個 reference。

因此「要怎麼讓傳入函數的變數隨著函數內部對它操作而跟著變動」這個疑惑就解開了,Java 所謂的「只有 call-by-value」的 value 指的就是「物件的 reference」,既然物件的 reference 被複製一份進去函數,那當然可以透過函數內部操作該 reference 來改變外部的物件 (而且不需要用 -> 運算元)。

這裡又冒出一個問題,既然原生型別的物件在 Java 當中是直接 hold 物件的值,所以傳入函數參數的預設行為就是 call-by-value,那麼如果想要實現 call-by-reference 的語意該怎麼做呢?其實也很簡單,就是將該原生型別的變數包裝成一個陣列,再傳入函數即可。

public static void increment(int[] array, int amount)
{
   array[0] = array[0] + amount;
}

public static void main(String args[])
{
   int[] myInt = { 1 };

   increment (myInt, 5);

   System.out.println ("Array contents : " + myInt[0]);
}

參考資料:
Java is Pass-by-Value, Dammit! - Scott Stanchfield
http://javadude.com/articles/passbyvalue.htm

Q&A : How do I pass a primitive data type by reference?
http://www.javacoffeebreak.com/faq/faq0066.html

... ...

6/02/2011

[C++] Reference 和 Pointer 的差異

在 C++ 當中 Reference 和 Pointer 都是一種間接取值的方法,既然兩者的功能那麼相近,到底為什麼要有 Reference 的存在呢?針對找到的資訊作一些整理如下:

  • Reference 和 Pointer 在功能和使用上的差異
  1. A pointer can be re-assigned any number of times while a reference can not be reassigned after initialization
  2. A pointer can point to NULL while reference can never point to NULL
  3. You can't take the address of a reference like you can with pointers
  4. There's no "reference arithmetics" (but you can take the address of an object pointed by a reference and do pointer arithmetics on it as in &obj + 5)

C++ 標準並沒有規定 compiler 要怎麼實作 Reference,但是似乎背後還是用指標的方式實現,所以在效能上並無差異。

  • Reference 的存在意義
  1. I believe the key insight into why C++ has reference types as well as pointer types is that reference types enable overloaded operators to look like built-in operators, as well as act like them.
  2. Pointers can do almost everything that references can do, but they can lead to expressions that don't look right. On the other hand, references have some restrictions that make them less convenient than pointers for implementing algorithms and data structures. References reduce, but do not eliminate, the need for pointers.
  3. As a general rule, use references in function parameters and return types to define attractive interfaces. Use pointers to implement algorithms and data structures.

參考資料: