2012-12-12 55 views
0

我有一个函数是相同的常量引用参数

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

是否有可能,如果我做的行为会改变const的参数吧:

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

您可以自由定义的A型如你所愿。当然。

回答

8

在第一次重载中,h不能更改'a'。它在'h'的主体中用于所有目的。 但是,这涉及复制构造函数来复制初始化'a'。

因此,在第一种情况下,它需要'A'中的可访问拷贝构造函数。同样的道理,它需要在A中有一个可访问的析构函数。在第二种情况下,不需要复制初始化,因此不需要'A'的可访问拷贝构造函数/析构函数。

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

在C++ 11中,第一个函数需要'A'根据调用'h'的方式需要一个可访问的'copy'或'move'构造函数。

+0

+1; “切片”可能会导致很难调试错误。 –

0

简短的回答:第

较长的回答:你的第一个例子中,在栈上创建的a完整副本。不管你用什么函数调用,A的拷贝构造函数都会被调用,用于传入的参数。当函数退出时,将调用a的析构函数。取决于您的实施A,可能会非常昂贵。

此外,对于抽象类(如果A是抽象类),如果使用从A派生的类调用,则复制构造函数不可访问的对象将无法调用第一个函数,该函数内接收到的副本将被切片。

第二个函数没有这些限制。

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

+0

对发生什么的一个很好的解释,但是行为_could_会根据复制构造函数中发生的情况而改变。 – icabod

+0

好吧,如果类有可变成员,改变原型可以改变行为。如果通过const引用传递'a',const方法仍然可以影响函数外部的状态。 –

1

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

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

实际上这一切都取决于A实际上做了什么。

0

除了别人在这里写的 拷贝构造a和潜在的切片成本的问题,如果这 被传递一些归类,从A在第一种情况下得到的,这些功能 有不同的签名。

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

如果再通过一个指向基类和 调用在派生类hh从派生类被称为他们的签名必须 相同。否则,将调用基类中的h。这可能是 可观察到的差异。

相关问题