Thursday, May 22, 2008

Call by XXX

轉錄自Ptt C_and_CPP版
參考網址 : http://sandwichc.blogspot.com/2007/02/cc-pointer-reference.html
// 測試用,不封裝
class Type {
    public : 
        Type() { i = 0 }
    int i;
};
1. call by Value (非 pointer):
修改 o 的資料是不會影響到 t 的 因為 o 是 t 的複本
void Value_Not_Pointer(Type o) {
    printf("%d ",o.i);  
    o.i = 3;   
    printf("%d ",o.i);
}

int main(){
    Type t;
    printf("%d ",t.i);  
    Value_Not_Pointer(t); 
    printf("%d ",t.i);
    return 0;
}
output : 0 0 3 0

2. call by Value (是 pointer): 一般稱作 call by Address Or call by Pointer
指派 o 到新的物件是不會影響到 t 的 因為 o 是 t 的複本
這個複本是指 o 與 t 所指到的物件是相同的物件
所以如果透過 o 去修改物件的話,則 t 所讀到的物件會受到影響
void Value_Is_Pointer_1(Type *o) { 
    printf("%d ",o->i); 
    o->i = 3; 
    printf("%d ",o->i);
}

int main(){  
    Type *t = new Type();
    printf("%d ",t->i);
    Value_Is_Pointer_1(t); 
    printf("%d ",t->i);
    return 0;
}
output : 0 0 3 3
------------------------------------------------------------------------
void Value_Is_Pointer_2(Type *o) { 
    printf("%x ",o);
    o = new Type();   
    printf("%x ",o);
} 

int main(){ 
    Type *t = new Type();
    printf("%x ",t); 
    Value_Is_Pointer_2(t); 
    printf("%x ",t);
    return 0;
}
output : 3d24b0 3d24b0 3d2548 3d24b0



3. call by Reference (非 pointer) 因為 o 就是 t 本身,某種程度上來說 o 是 t 的同名(alias)
所以在修改 o 的時候, t 是會受到影響的
在某種意涵上, call by Reference 與 call by Address 是相同的
void Reference_Not_Pointer(Type &o) {
    printf("%d ",o.i);
    o.i = 3;
    printf("%d ",o.i);
} 

int main(){
    Type t;
    printf("%d ",t.i);
    Reference_Not_Pointer(t);
    printf("%d ",t.i);
    return 0;
}
output : 0 0 3 3


4. call by Reference (是 pointer)
因為 o 是 t 本身,所以在透過 o 修改物件時,t 是會受到影響的
而且如果將 o 重新指派新的物件時,t 也會只到新的物件上
void Reference_Is_Pointer_1(Type *&o) {
printf("%d ",o->i);
    printf("%d ",o->i);
    o->i = 3;
printf("%d ",o->i) } int main(){ Type *t = new Type(); printf("%d ",t->i); Reference_Is_Pointer_1(t); printf("%d ",t->i); return 0; }
output : 0 0 3 3
------------------------------------------------------------------------
void Reference_Is_Pointer_2(Type *&o) {
    printf("%x ",o);
    o = new Type();
    printf("%x ",o);
}

int main(){
    Type *t = new Type();
    printf("%x ",t);
    Reference_Is_Pointer_2(t);
    printf("%x ",t);
    return 0;
}
output : 3d2460 3d2460 3d24c8 3d24c8