我有一个问题,可能有点蠢,但现在我需要弄清楚。
考虑带有一些参数和返回类型的常规函数。
我的问题是:
参数总是会被复制吗?即使函数期望参数为引用或指针,也会创建新的引用/指针,对吧?当函数结束时,这些参数会被销毁吗?
返回值是否也是从实际执行函数的上下文中复制的?或者它们只是某个地址,而上下文中的值也被销毁了?
如果您能以自己的方式解释调用函数时内存的工作原理,我将不胜感激。我对处理器的功能只有一般的了解,但我已经使用过汇编语言,所以至少有些东西可以借鉴。
我有一个问题,可能有点蠢,但现在我需要弄清楚。
考虑带有一些参数和返回类型的常规函数。
我的问题是:
参数总是会被复制吗?即使函数期望参数为引用或指针,也会创建新的引用/指针,对吧?当函数结束时,这些参数会被销毁吗?
返回值是否也是从实际执行函数的上下文中复制的?或者它们只是某个地址,而上下文中的值也被销毁了?
如果您能以自己的方式解释调用函数时内存的工作原理,我将不胜感激。我对处理器的功能只有一般的了解,但我已经使用过汇编语言,所以至少有些东西可以借鉴。
C++和C一样,是一种按值传递的语言,因此通常会复制参数。
当:
void f( int x ) {
}
在调用函数时,会创建其参数的副本并传递到函数中。当:
void f( int * x ) {
}
当调用函数时,如果传递的是指针,则会复制指针并将其传递给函数。
但是,如果使用引用,则不会进行复制:
void f( int & x ) {
}
没有复制被创建,但内部可能使用指针来传递参数的地址 - 但您不应该考虑这一点。
对于返回值也是完全相同的情况:
int f() {
return 1;
}
函数返回值为1的副本,并返回给调用者。如果函数返回指针,则会复制指针。再次说明,引用是例外情况,因为不会复制引用,但在内部可能使用指针来返回值。
尼尔的答案是正确的,但请注意编译器允许进行优化。这被称为“复制省略”。可以在以下链接中找到关于此优化的非常好的解释:
http://cpp-next.com/archive/2009/08/want-speed-pass-by-value
struct foo f(struct bar x) { ... }
...
struct foo myfoo;
struct bar mybar;
myfoo = f(mybar);
f()按值传递一个结构体(即在其上制作一个临时副本,通常在堆栈上),并且f()还返回一个不同的结构体,该结构体被复制到mybar中。
构造函数和析构函数分别在对象创建和销毁时调用,但在引用和指针的情况下不会被调用。
在引用/指针作为参数的情况下,只复制地址而不是数据;而在对象作为参数的情况下,实际数据被复制(对于具有深度继承层次结构的对象来说代价很高)。