const参数是否与const参考参数相同

时间:2012-12-12 13:20:10

标签: c++ const

我有一个功能

void h(A const a){...};

如果我这样做,行为是否有可能改变:

void h(A const &a){..same body as above..};

您可以根据需要自由定义类型A.当然。

4 个答案:

答案 0 :(得分:8)

在第一次重载时,h不能改变'a'。它的所有目的都是'h'体中的const。 但是,这涉及复制初始化'a'的复制构造函数。

因此,在第一种情况下,它需要'A'中的可访问复制构造函数。出于同样的原因,它需要A中的可访问的析构函数。

在第二种情况下,不需要复制初始化,因此不需要'A'的可访问复制构造函数/析构函数。

此外,在第一种情况下,如果'A'的派生对象作为参数传递,'a'将进行'切片'。第二个函数不会出现“切片”问题,因为基类引用可以绑定到派生对象。因此,在这种情况下也不需要可访问的析构函数。

在C ++ 11中,第一个函数需要'A'才能拥有一个可访问的'copy'或'move'构造函数,具体取决于调用'h'的方式。

答案 1 :(得分:1)

根据类型A的复制构造函数中发生的情况,是的,您可以获得不同的行为。

正如其他答案中所提到的,传递值而不是引用将导致执行A的复制构造函数,这是代码的单独路径。如果您的类A处理某些资源,那么复制该类可能最终会将该资源的不同实例传递给该函数。

实际上,这完全取决于A实际上做什么。

答案 2 :(得分:0)

简短回答:不。

更长的答案:在第一个示例中,在堆栈上创建了a的完整副本。无论你将函数调用为什么,都会为你传入的参数调用A的复制构造函数。当函数退出时,将调用a的析构函数。取决于A的实施,这可能非常昂贵。

另外,对于复制构造函数不可访问的对象,对于抽象类(如果A是抽象的),如果使用从A派生的类调用,则不能调用第一个函数,副本收到的功能将被切成薄片。

第二个功能没有受到这些限制。

TL; DR:你永远不应该使用第一个版本(但你的里程可能会有所不同)。

答案 3 :(得分:0)

除了其他人在这里写的有关费用的内容 复制构建a和潜在的切片问题,如果这样 在第一种情况下,传递了从A派生的一些分类,这些函数 有不同的签名。

如果h是某个类的成员函数并尝试覆盖virtual 函数h在基类中,两个表单将被视为不同 功能,因为他们的签名不同。这意味着第一种形式不能 超载第二个。

如果然后通过指向基类的指针在派生类中调用h 希望从派生类中调用h,他们的签名必须是 相同。否则将调用基类中的h。这可以 做出可观察到的差异。