我可以使用以下代码片段:
C *pa1 = new C(c2);
我将它转移到另一个函数:
foo(pa1);
提前感谢我究竟要转移实际指针或其副本 并且有人可以提供一些信息,告诉我们在哪些情况下复制信息,并在其中转移实际指针
foo声明:
foo(A const *pa)
答案 0 :(得分:1)
由于pa1
是指向C的类型,因此您将指向C的指针传递给函数foo
。您没有复制实际对象。
要传递一个对象,你需要foo来获取一个C类型的对象,并在传递它时取消引用pa1
:
void foo(C);
...
foo(*pa1);
答案 1 :(得分:1)
假设foo被声明为:
void foo(C* p);
您正在传递指针的副本。
这意味着,如果foo这样做:
p = &some_other_object;
调用者不会看到对指针的更改。
这也意味着我们正在复制指针,而不是指向的东西。如果foo这样做:
p->bar = "Smurf!"
调用者中的pa1也会看到更改。出于这个原因,指针通常用于实现一种传递引用。
如果声明了foo:
void foo(C*& p);
然后p将是对pa1的引用,对p的更改将导致对pa1的更改。从历史上看,这也是使用指针指针实现的:
void foo(C** p);
在这种情况下你可以像这样调用foo:
foo(&pa1);
和foo可以做类似的事情:
*p = &some_other_object;
更改pa1指向的内容。
答案 2 :(得分:0)
由于pa1
是指针(因为您已将其定义为C *
),因此您将指向C对象的指针传递给foo
。
那就是说,无论是通过值还是通过引用传递指针都是未知的,而没有看到foo
的声明。
答案 3 :(得分: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);