传递const&对象与const对象的区别

时间:2013-05-14 14:06:53

标签: c++ const

假设您有类似这样的功能

bool verifyObject(const myObj& obj);

或者这个

bool verifyObject(const myObj obj);

据我了解,当你传递第二种情况时,会复制一份副本。但是,编译器可能会利用constness在第一种情况下传递。因此,我认为以任何一种方式传递const对象没有区别。

我错了吗?

3 个答案:

答案 0 :(得分:3)

第二个,从来电者的角度来看相当于

bool verifyObject(myObj obj);

此外,作为声明,这两者完全等同:

bool verifyObject(myObj obj);
bool verifyObject(const myObj obj);

在函数声明中忽略所有顶级consts。差异仅在定义

期间显现
bool verifyObject(const myObj obj)
{
    obj.NonConstMethod(); //compiler error!
}

您无法修改函数内的副本,调用者根本不关心。它只是出于您自己的目的,作为函数实现者。

答案 1 :(得分:2)

  

据我所知,当你传递第二种情况时,会复制一份。

是;虽然在某些情况下(例如临时通过时)可以省略副本。

  

但是,编译器可能会利用constness来传递第一种情况。

没有;除非论证是暂时的,否则这不是可以省略副本的情况之一。在调用函数时,编译器甚至可能不知道函数中的参数是const,因为在声明函数时可以省略这样的顶级const。因此,即使它可以确定传递引用将等同于传递副本(如果复制构造函数或析构函数具有可观察的副作用,或者如果类具有可变成员,则不会是这种情况),它不能更改调用约定,因为调用者无法知道该更改。

话虽如此,如果函数是内联函数,或者您的编译器执行整个程序优化,那么这样的优化是可能的;但只有当他们不改变程序的行为时才会这样做。

答案 2 :(得分:1)

使用第二个示例(传递值),const修饰符几乎没有区别,因为编译器将调用对象的复制构造函数并传递它的副本。 另一方面,通过const引用(const myObj& obj)传递仅传递对象的引用(不进行复制)。在这种情况下,被调用的函数不能通过obj改变对象的状态。