我一直在阅读有关复制省略和返回值优化如何通过避免调用对象复制构造函数来提高速度的信息。我了解这些机制是如何工作的,但我想知道这是否会导致程序的行为与预期不同。
本质上,我的问题是;如果我们编写复制构造函数而不创建作为另一个对象副本的对象会发生什么?换句话说,如果
AClass original;
AClass copy ( original );
// copy == original -> false
比如说,我们有一个这样的类:
// AClass.hpp
struct AClass
{
static int copyCount;
int copyNumber;
AClass():copyNumber(0){}
AClass( AClass const& original ):copyNumber(++copyCount){} // I think this is the signature for the copy constructor
};
// AClass.cpp
int AClass::count ( 0 );
这显然是一种可怕的行为,我并不是说我会做这样的事情。然而,重点是存在的;如果我们依赖副本的副作用怎么办?在此示例中,跟踪我们制作了多少副本。我希望优化不应该影响程序的运行方式。但是,复制省略可能会导致以下代码失败:
// Main.cpp
AClass MakeAClass()
{
return AClass();
}
int main()
{
AClass copy ( MakeAClass() );
if ( AClass::copyCount == 1 )
{
return 0;
}
else
{
return -1;
}
}
当我在没有优化的调试模式下构建时,这可能会返回 0,但是当我打开优化并且从 MakeAClass 的返回直接放在副本上时突然失败,跳过了复制构造函数。
当编译器尝试这些优化以寻找副作用时,是否有检查?当您要求副本时,期望代码执行副本是错误的吗?