按值或常量引用传递
Pass by value or const reference?
有一组很好的规则来确定是按值传递还是按常量引用传递
- 如果函数打算更改参数作为副作用,请采取它通过非常量引用。
- 如果函数不修改其参数,并且参数为基元类型,按值获取。 否则,请
- 通过常量引用来获取,但以下情况除外cases:如果函数需要复制 const无论如何,请按值获取。
对于下面的构造函数,如何确定?
class A
{
public:
A(string str) : mStr(str) {} // here which is better,
// pass by value or const reference?
void setString(string str) { mStr = str; } // how about here?
private:
string mStr;
};
在这种特殊情况下,假设 C++11 并移动字符串的构造/赋值,您应该按值获取参数并将其移动到构造函数的成员。
A::A(string str) : mStr(std::move(str)) {}
二传手的情况有点棘手,我不确定你是否真的想要/需要优化它的每一点......如果要最大程度地优化,可以提供两个重载,一个采用右值引用,另一个采用常量左值引用。无论如何,常量左值引用可能是一个足够好的方法:
void A::setString(string const& str) { mStr = str; }
为什么会有差异?
在构造函数的情况下,成员尚未构建,因此需要分配内存。您可以将该内存分配(以及数据的实际复制,但这是租赁器成本)移动到接口,这样,如果调用方有临时内存,则可以在没有额外内存分配的情况下转发它。
在分配的情况下,事情有点复杂。如果字符串的当前大小足够大以容纳新值,则不需要分配,但如果字符串不够大,则需要重新分配。如果将分配移动到接口(按值参数),即使不需要,也将始终执行。如果分配是在函数(const 引用参数)内完成的,那么对于一小组情况(参数是临时的,大于当前缓冲区的情况),将完成本来可以避免的分配。
您网站的文章不是软件的良好参考工程。 (它也很可能已经过时,因为它谈论移动语义,日期为 2003 年。
一般规则很简单:通过常量引用传递类类型,和其他按值划分的类型。 有明确的例外:在与标准库的约定保持一致,它也是通常按值传递迭代器和函数对象。
其他任何事情都是优化,不应该在探查器说你必须这样做。
在这种情况下,最好通过常量引用传递参数。原因:字符串是一种类类型,你不修改它,它可以是任意大的。
最好使用成员初始化列表来初始化值,因为它具有以下优点:
1) 赋值版本,创建一个默认构造函数来初始化 mStr,然后在默认构造的构造值之上分配一个新值。使用 MIL 可避免这种浪费的构造,因为列表中的参数用作构造函数参数。
2)这是初始化常量变量的唯一地方,除非这些只是您可以在类中使用枚举的交互器。 枚举 T{v=2};
3)这是初始化引用的地方。
这就是我的建议:
#include <iostream>
#include <string>
class A
{
private:
std::string mStr;
public:
A(std::string str):mStr(str){}
//if you are using an older version of C++11, then use
//std::string &str instead
inline const void setString(std::string str)
{
mStr = str;
}
const std::string getString() const
{
return mStr;
}
};
int main()
{
A a("this is a 1st test.");
a.setString("this is a 2nd test.");
std::cout<<a.getString()<<std::endl;
}
看看这个:http://www.cplusplus.com/forum/articles/17820/
- 什么时候在C++中返回常量引用是个好主意
- 我想将一个对T类型的非常量左值引用绑定到一个T类型的临时值
- 为什么我可以通过引用修改常量返回
- 返回常量对象引用 (getter) 和仅返回字符串有什么区别?
- 将常量指针引用绑定到非常量指针
- 通过常量引用传递参数的矩阵模板类
- 按值捕获引用时出现非常量
- 在C++中使用非常量引用作为常量
- 具有常量引用参数的函数模板专用化
- 多个"常量引用"变量可以共享同一个内存吗?
- 为什么 STL 容器适配器堆栈中的 top 返回常量引用?
- 为什么按值传递QStringView比引用常量更快?
- 通过引用常量函数调用另一个类的非常量函数
- 构造常量对象与引用常量对象
- 引用“常量value_type”时出错
- 为什么可以在 for 语句中重新分配引用常量
- 程序反馈:命名循环索引和引用常量数据
- 堆还是栈?在c++中函数调用中引用常量字符串时
- 为什么常量结构数组在按名称引用常量结构时不放在 .rodata 中?
- 为什么编译器允许在函数中发送对迭代器的引用,该函数引用常量迭代器