提问人:devoured elysium 提问时间:7/21/2009 最后编辑:Jan Schultkedevoured elysium 更新时间:9/27/2023 访问量:4307
默认情况下,对象是按值传递还是按引用传递?
By default, are objects passed by value or by reference?
问:
来自 C#,其中类实例通过引用传递(即,在调用函数时传递引用的副本,而不是值的副本),我想知道这在 C++ 中是如何工作的。
在以下情况下,是复制 to 的值,还是什么?_poly = poly
poly
_poly
#include <vector>
class polynomial {
std::vector<int> _poly;
public:
void Set(std::vector<int> poly) { poly_ = poly; }
};
答:
这将复制整个向量。赋值是按 C++ 中的值进行的。如果要分配指针,则会分配指针值。一旦初始化,引用就不能重新赋值以引用另一个对象,因此赋值引用会更改引用对象。
向量的复制运算符将复制向量的内容。
这将对整数向量进行浅拷贝。这通常会像您预期的那样工作(_poly最终将包含与 poly 相同的值)。
如果你有指针,你会看到一些奇怪的行为(因为它们会被值复制)。
通常,您希望通过 const 引用传递该参数:
void polynomial::Set( const vector<int>& poly )
在这种情况下,通过常量引用传递不会影响结果,并且会更有效,因为它将消除传递到方法中的向量的不需要副本。
评论
poly
的值将被复制到 -- 但您将在此过程中制作一个额外的副本。更好的方法是通过 const 引用:_poly
void polynomial::Set(const vector<int>& poly) {
_poly = poly;
}
编辑我在关于复制和交换的评论中提到过。实现所需内容的另一种方法是
void polynomial::Set(vector<int> poly) {
_poly.swap(poly);
}
这为您提供了额外的好处,即拥有强大的异常保证而不是基本保证。在某些情况下,代码也可能更快,但我认为这更像是一种奖励。唯一的问题是,这段代码可能被称为“更难阅读”,因为人们必须意识到有一个隐式副本。
评论
是的,您指向的线正在复制整个向量。此外,函数调用上也会有一个副本,因为这不是 const。
基本上,如果向量有任何大小,这是非常昂贵的。
除非您通过引用(使用 & 前缀)分配或传递参数,否则您将按值传递。对于类,这意味着对象的副本是使用为该类型提供的或隐式生成的(浅层)复制构造函数构造的。这可能很昂贵 - 而且通常是不可取的。
在示例中,向量被复制两次 - 一次是作为参数传递给 Set() 方法时,另一次是将其分配给_poly成员时。
您可以通过引用传递向量来避免第一个副本:
void polynomial::Set(const vector<int>& poly) // passes the original parameter by reference
{
_poly = poly; // still makes a copy
}
有三种可能性:
按值传递
void someFunction(SomeClass theObject);
传递指针
void someFunction(SomeClass *theObject);
通过引用传递
void someFunction(SomeClass &theObject);
评论
您的矢量将被复制。
实际情况是,vector 的“=”运算符已被重载以执行实际复制。
上一个:在 C++ 中创建和删除对象
评论