我最近编写了一段代码
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());?
非常感谢!
答案 0 :(得分:4)
我认为这两种情况没有任何区别。两次都会调用相同的复制构造函数。
您确定完全您在代码中写了什么吗?
答案 1 :(得分:2)
严格地说,在第一种情况下,默认构造函数被调用,后跟赋值运算符,在第二种情况下,它只使用复制构造函数。
好吧,我最初的假设是错误的,显然在这两种情况下只会调用复制构造函数(在赋值情况下也可以调用另外的“转换”构造函数)。我会在睡眠后启动编译器并在我的开发环境中验证它。
答案 2 :(得分:1)
您可以在复制构造函数中放置断点(甚至是printf语句),并且您知道它何时被调用。 SO无法取代基本调试。 ;)
但是,是的,应该在前两种情况下调用复制构造函数。第三种情况使用赋值运算符。
您是否尝试在调试器中运行它?它应该打破ABORT信号。
答案 3 :(得分:0)
在最纯粹的理论中,应该在两种情况下调用复制构造函数。 但是,有一种称为返回值优化(RVO)的东西,允许编译器在这些情况下使用它。如果使用RVO,则不会调用复制构造函数。也许你的编译器在一种情况下使用RVO而不是另一种情况?
编辑: 这仅适用于案例
SomeClass someObject;
mysqlpp::StoreQueryResult result;
result = someObject.getResult();
答案 4 :(得分:0)
答案 5 :(得分:0)
我认为第一种情况是赋予对象值(权利值)。它是向对象发送值。2,3示例是隐式对象和显式对象概念。您不应该通过赋值将代码写入直接对象。