2010-06-15 21 views
1

我可以有代碼的這個片斷:傳輸參數++

C *pa1 = new C(c2); 

,我轉移到另一個功能:

foo(pa1); 

究竟是什麼我傳遞實際指針或複印件,謝謝提前 並能有人給一些信息關於在哪些情況下信息被複制,並在其中我轉移實際的指針

聲明的foo:

foo(A const *pa) 
+0

我在上一個問題中寫了一個關於不同參數語義的長篇解釋,你可能想看一看。 http://stackoverflow.com/questions/2139224/how-to-pass-objects-to-functions-in-c/21​​39553#2139553 – 2010-06-15 07:38:24

回答

1

假設foo的聲明。

這意味着,如果foo的功能如下:

p = &some_other_object; 

是改變指針不會被調用者可以看到。

這也意味着我們正在複製指針,而不是東西指着。如果foo這麼做:

p->bar = "Smurf!" 

pa1在調用者中也會看到變化。出於這個原因,指針經常被用來實現一種通過引用。

如果被宣佈爲富:

void foo(C*& p); 

那麼p將PA1參考,並修改爲P會導致變化PA1。歷史上,這也被使用指針的指針來實現:

在這種情況下
void foo(C** p); 

你調用foo這樣的:

foo(&pa1); 

和Foo可以這樣做:

*p = &some_other_object; 

到改變pa1指向的內容。

+0

好的,謝謝,但如果我想傳輸實際的指針呢?不是它的副本,我需要使用兩個**嗎? – lego69 2010-06-15 06:37:39

+0

我認爲你需要解釋你的意思是「轉移」。如果你希望一個函數能夠修改指針,使得調用者的指針改變,那麼是的,你確實需要C **而不是C *,並且調用foo(&pa1)。 – camh 2010-06-15 06:41:07

+0

@camh:或'void foo(C * & p);',並且不需要改變呼叫。 – 2010-06-15 07:35:12

1

由於pa1的類型爲指針到C,要傳遞一個指針到C到功能foo。您不復制實際的對象。

要傳遞一個對象,你會傳遞,當它需要FOO採取C型和取消引用pa1的對象:

void foo(C); 
... 
foo(*pa1); 
+0

但指針本身怎麼樣,我複製它嗎? – lego69 2010-06-15 06:30:46

+0

指針被複制。在你調用foo的函數中,它保存着一個指向C(在pa1中)。在foo中,它包含一個指向C的指針(在它的實際參數中)。因此指針被複制。你是這個意思嗎? – camh 2010-06-15 06:35:58

0

由於pa1是一個指針(如你將它定義爲一個C *) ,您正在將一個指向C對象的指針傳入foo

也就是說,無論您是通過值還是通過引用傳遞指針,未知foo的聲明都是未知的。

void foo(C* p); 

您傳遞指針的副本:作爲

+0

你可以給我兩個聲明,這將顯示這兩種方法在這種情況下傳輸的差異 – lego69 2010-06-15 06:34:02

0
C *pa1; 

對象類型的「C *」是在堆棧上創建(局部變量PA1)類型的

pa1 = new C(c2); 

對象上的堆被創建「C」,它的地址返回到「PA1 「可變

foo(pa1) 

我們可以說‘類型的對象‘C *’(可變PA1)由值傳遞給函數foo,那麼函數獲取指針的一個拷貝’,
但是「類型'C'的對象(這個在堆上創建的對象)通過引用(通過指針)傳遞給函數foo,因此不會創建副本'C'對象。

要傳遞通過引用(無需製作對象的副本),可以使用對對象的C++引用或指向對象的指針。它們在進行函數參數傳遞時的作用類似,也就是說,下面4行中的所有行都具有相同的效果,通過引用(這些是const引用,刪除const關鍵字以便能夠通過foo函數永久修改對象):

foo(const A *pa) { pa->DoSth(); } /*...*/ foo(some_pointer); 
foo(const A *pa) { pa->DoSth(); } /*...*/ foo(&some_reference); 
foo(const A &pa) { pa.DoSth(); } /*...*/ foo(*some_pointer); 
foo(const A &pa) { pa.DoSth(); } /*...*/ foo(some_reference);