2008-04-18

C++ Array of References?

It's legal to get reference of dynamical allocated object:

std::vector<double> *vec = new std::vector<double>(5); std::vector<double> &vec0Ref = *vec;

Use it:

#include <iostream> #include <vector> int main(){ size_t *n = new size_t; std::cin >> *n; std::vector<double> *vec = new std::vector<double>[*n]; // No error when vec is Pointer to Nothing! (*n == 0/1) // It is dangerous using dynamic array... std::vector<double> &vec0Ref = vec[0]; std::vector<double> &vec1Ref = vec[1]; double *a = new double; std::cin >> *a; vec0Ref.push_back(*a); //runtime-error when *n <= 0 std::cout << vec0Ref[0] << std::endl; vec1Ref.push_back(*a); //runtime-error when *n <= 1 std::cout << vec1Ref[0] << std::endl; }

Note:

會想到要拿到動態物件的 reference,是因為想要在物件建立後使用 array of references 取代 array of pointers ,用來放 sorting 的結果或做 mapping。但發現 It's illegel!

reference 並不能用來作為 array 或 container 的元素。基本上,reference 並不是物件,因此沒有辦法複製它,或改變其內容(指reference本身);其意義只是物件的別名。在JAVA/C#中的意義又不太一樣了;reference 感覺像是 const pointer。

當我們要對已存在的數個物件做 mapping,sorting 之類的動作,只能使用 array of pointers 來避免複製物件。之前會想要使用 reference 是因為書上說使用 reference 比 pointer 自然,也錯把 reference 視作 const pointer。(以前學JAVA= =)然而在這種情況下,使用 array of pointers 才是合理且正確的用法。

Another Test:

#include <iostream> int main(){ //existing objects int a=1, b=2; int arr[2] = {a,b}; // correct //error: declaration of `refs' as array of references int &refs[2] = {a,b}; //error! //array of pointers to integer int *ptrs[2] = {&a,&b}; // correct //reference of arr[2] int (&ref)[2] = arr; // correct //pointer to arr[2] int (*ptr1)[2] = &arr; // correct //assign "array" to "pointer to array" int (*ptr2)[2] = arr; // error! //pointer to first element of array int *ptr3 = arr; // correct std::cout <<"arr="<<arr<<" arr[1]="<<arr[1]<< std::endl <<"ref="<<ref<<" ref[1]="<<ref[1]<<std::endl <<"ptr1="<<ptr1<<" *ptr1="<<*ptr1 <<" (*ptr1)[1]="<<(*ptr1)[1]<<std::endl <<"ptr3="<<ptr3<<" ptr3[1]="<<ptr3[1]<<std::endl; std::cout <<"sizeof(arr)="<<sizeof(arr)<<std::endl <<"sizeof(ref)="<<sizeof(ref)<<std::endl <<"sizeof(ptr1)="<<sizeof(ptr1)<<std::endl <<"sizeof(*ptr1)="<<sizeof(*ptr1)<<std::endl <<"sizeof(ptr3)="<<sizeof(ptr3)<<std::endl; }
將錯誤去掉後的執行結果:
arr=0012FF5C arr[1]=2 ref=0012FF5C ref[1]=2 ptr1=0012FF5C *ptr1=0012FF5C (*ptr1)[1]=2 ptr3=0012FF5C ptr3[1]=2 sizeof(arr)=8 sizeof(ref)=8 sizeof(ptr1)=4 sizeof(*ptr1)=8 sizeof(ptr3)=4

可見 array of reference 不合法。

此外,雖然 ptr3 跟 arr 幾乎等效,ptr3 其實還是 pointer to int(arr[0]) 而非 array name。而 ptr1 是 pointer to arr,因此*ptr1 就是 arr。

No comments:

Post a Comment