我有一个函数是相同的常量引用参数
void h(A const a){...};
是否有可能,如果我做的行为会改变const的参数吧:
void h(A const &a){..same body as above..};
您可以自由定义的A型如你所愿。当然。
我有一个函数是相同的常量引用参数
void h(A const a){...};
是否有可能,如果我做的行为会改变const的参数吧:
void h(A const &a){..same body as above..};
您可以自由定义的A型如你所愿。当然。
在第一次重载中,h不能更改'a'。它在'h'的主体中用于所有目的。 但是,这涉及复制构造函数来复制初始化'a'。
因此,在第一种情况下,它需要'A'中的可访问拷贝构造函数。同样的道理,它需要在A中有一个可访问的析构函数。在第二种情况下,不需要复制初始化,因此不需要'A'的可访问拷贝构造函数/析构函数。
此外,在第一种情况下,如果将'A'的派生对象作为参数进行传递,'a'将进行'切片'。第二个函数不会有“切片”问题,因为基类引用可以绑定到派生对象。因此,在这种情况下也不需要可访问的析构函数。
在C++ 11中,第一个函数需要'A'根据调用'h'的方式需要一个可访问的'copy'或'move'构造函数。
简短的回答:第
较长的回答:你的第一个例子中,在栈上创建的a
完整副本。不管你用什么函数调用,A的拷贝构造函数都会被调用,用于传入的参数。当函数退出时,将调用a
的析构函数。取决于您的实施A
,可能会非常昂贵。
此外,对于抽象类(如果A
是抽象类),如果使用从A
派生的类调用,则复制构造函数不可访问的对象将无法调用第一个函数,该函数内接收到的副本将被切片。
第二个函数没有这些限制。
TL; DR:你不应该使用第一个版本(但你的里程可能会有所不同)。
对发生什么的一个很好的解释,但是行为_could_会根据复制构造函数中发生的情况而改变。 – icabod
好吧,如果类有可变成员,改变原型可以改变行为。如果通过const引用传递'a',const方法仍然可以影响函数外部的状态。 –
根据您的类型A
的复制构造函数中发生的情况,是的,您可能会得到不同的行为。
正如其他答案中所提到的,传递值而不是引用将导致执行拷贝构造函数A
,这是一个单独的代码路径。如果您的类A
处理某些资源,则复制该类最终可能会将该资源的另一个实例传递给该函数。
实际上这一切都取决于A
实际上做了什么。
除了别人在这里写的 拷贝构造a
和潜在的切片成本的问题,如果这 被传递一些归类,从A
在第一种情况下得到的,这些功能 有不同的签名。
如果h
是一些类的成员函数,并尝试在基类,因为它们的签名不同的两种形式将被视为不同 函数来覆盖virtual
功能h
。这意味着第一种形式不能超载第二种。
如果再通过一个指向基类和 调用在派生类h
想h
从派生类被称为他们的签名必须 相同。否则,将调用基类中的h
。这可能是 可观察到的差异。
+1; “切片”可能会导致很难调试错误。 –