为什么要将对象的副本作为函数的参数?为什么const-ref不是参数的默认方式



尽管我很喜欢C++编程,但有一件事我真的不懂。对我来说,似乎最常见的函数编程方式是这样的:

some_function(a variable)
do something according to the data in the variable

示例:

bool match_name(const std::string& name)
{
return this->name == name;
}

我发现自己的代码中90%的函数参数都使用const-ref(也许我做错了什么(。

我的问题是:为什么变量的副本是参数的"默认"类型?为什么const-ref不是默认值?

为什么不做一些类似的事情?:

void my_function(My_type object)      // <- const ref
void my_function(ref My_type object)  // <- ref (mutable)
void my_function(copy My_type object) // <- copy

除了历史原因外,这将产生非常丑陋的影响。这基本上意味着MyType myVarName在作为函数的作用域时或在函数参数列表中使用时将具有不同的含义。

void foo(MyType myVar) //myVar is const ref
{
MyType anotherVar = myVar; // anotherVar is a copy, what?
const MyType& myVarRef = myVar; //a reference, but it looks like it has different type than myVar?
}

想想可怜的&!除非你提出一种不同的方法来区分裁判和非裁判,否则你最终会得到

void foo(MyType& myVar) //myVar is a copy?
{
MyType& anotherVar = myVar; // anotherVar is a reference???
}

C++有一个很好的对象概念和对对象的引用。后者总是通过将&添加到类型来表示。你的提议会把它搞砸,C++会比现在更难理解。

C++希望与C兼容,由于C默认使用值语义,C++也是如此。按值获取内置类型而按引用获取其他类型是非常不一致的。

然而,通过引用传递并不总是更好的。引用引起的指针间接性通常会使编译器更难优化代码生成。在许多情况下,通过值传递类型仍然比通过引用传递要好。这取决于类型。指针间接引用可能会导致内存读取,而通过值传递可以在CPU寄存器中传递对象。例如,像这样的类型:

class Point {
public:
/* functions */
private:
int x;
int y;
};

应始终按值传递。它只是两个整数。引用可能会导致不必要的内存读取来获取值。

此外,有时您希望传递值,即使类型无法注册。例如,由于移动语义,需要存储传递值的所谓"接收函数"在处理值时表现更好。主要的例子是建设者和建设者:

void SomeClass::setString(std::string s)
{
this->s_ = std::move(s);
}

在这种情况下,通过引用传递可能会产生额外的副本。你可以在线阅读更多关于这方面的内容。一个好的起点是这个SO问题:

是传递conststd::string&作为参数结束?

相关内容

  • 没有找到相关文章

最新更新