C ++复制构造函数

时间:2009-01-02 12:08:00

标签: c++ constructor

我最近编写了一段代码

SomeClass someObject;
mysqlpp::StoreQueryResult result = someObject.getResult();

SomeClass :: getResult()的位置如下:

mysqlpp::StoreQueryResult SomeClass::getResult()
{
mysqlpp::StoreQueryResult res = ...<something>...;
return res;
}

现在,使用第一个代码片段中的示例,当我编译并运行时,程序崩溃了一个ABORT信号。然后我将第一个片段更改为:

SomeClass someObject;
mysqlpp::StoreQueryResult result(someObject.getResult());

工作得很好。另外,为了尝试一下,我又把它改成了:

SomeClass someObject;
mysqlpp::StoreQueryResult result;
result = someObject.getResult();

也很好。

现在,我只是想不通为什么第一个例子失败了,接下来两个成功了。据我所知,在第一个例子中,复制构造函数用于初始化结果。但是第二个例子中的情况也不是这样吗?那么为什么第二个例子成功呢?第三个例子更有意义 - 因为没有使用复制const,我们只是在构造之后分配。

简而言之,有什么区别:

FooClass a = someObject.someMethodReturningFooClassInstance();

FooClass a(someObject.someMethodReturningFooClassInstance());?

非常感谢!

6 个答案:

答案 0 :(得分:4)

我认为这两种情况没有任何区别。两次都会调用相同的复制构造函数。

您确定完全您在代码中写了什么吗?

答案 1 :(得分:2)

严格地说,在第一种情况下,默认构造函数被调用,后跟赋值运算符,在第二种情况下,它只使用复制构造函数。

好吧,我最初的假设是错误的,显然在这两种情况下只会调用复制构造函数(在赋值情况下也可以调用另外的“转换”构造函数)。我会在睡眠后启动编译器并在我的开发环境中验证它。

答案 2 :(得分:1)

您可以在复制构造函数中放置断点(甚至是printf语句),并且您知道它何时被调用。 SO无法取代基本调试。 ;)

但是,是的,应该在前两种情况下调用复制构造函数。第三种情况使用赋值运算符。

您是否尝试在调试器中运行它?它应该打破ABORT信号。

答案 3 :(得分:0)

在最纯粹的理论中,应该在两种情况下调用复制构造函数。 但是,有一种称为返回值优化(RVO)的东西,允许编译器在这些情况下使用它。如果使用RVO,则不会调用复制构造函数。也许你的编译器在一种情况下使用RVO而不是另一种情况?

编辑: 这仅适用于案例

SomeClass someObject;
mysqlpp::StoreQueryResult result;
result = someObject.getResult();

答案 4 :(得分:0)

实际上,第一个将使用operator =进行中间复制,而第二个将执行直接复制构造。

答案 5 :(得分:0)

我认为第一种情况是赋予对象值(权利值)。它是向对象发送值。2,3示例是隐式对象和显式对象概念。您不应该通过赋值将代码写入直接对象。