【发布时间】:2021-10-09 04:51:00
【问题描述】:
我查看了 Stack Overflow 上的相关问题,据我了解,main() 的第一行应该调用构造函数,第二行应该触发一次移动构造函数的调用(或移动构造函数时的复制构造函数被删除)。
#include <iostream>
#include <memory>
using namespace std;
class Node {
public:
Node() { cout << "Called contructor\n"; }
~Node() { cout << "Called destructor\n"; }
Node(const Node& other) { cout << "Called copy-contructor\n"; }
Node(Node&& other) { cout << "Called move-constructor\n"; }
};
int main(){
Node a = Node();
make_shared<Node>(a);
return 0;
}
但是我从上面的代码得到的结果是:
Called contructor
Called copy-contructor
Called move-constructor
Called destructor
Called destructor
Called destructor
在我看来是因为传参调用了拷贝构造函数,而make_shared的实现中调用了move构造函数,是吗?调用make_shared 时是否可以避免两次构造函数调用(例如使用指针的引用传递)?有什么方法可以通过总共调用一次构造函数来获得shared_ptr<Node>?
我的编译器版本:
Configured with: --prefix=/Library/Developer/CommandLineTools/usr --with-gxx-include-dir=/Library/Developer/CommandLineTools/SDKs/MacOSX.sdk/usr/include/c++/4.2.1
Apple clang version 12.0.5 (clang-1205.0.22.11)
Target: x86_64-apple-darwin20.5.0
Thread model: posix
InstalledDir: /Library/Developer/CommandLineTools/usr/bin
代码是使用默认参数的编译器:g++ test.cpp
【问题讨论】:
-
@rawrex 通过在
Node a = Node()前后输出,看来该行只触发了一次构造函数调用。 -
Node(const Node&& other)-- 去掉const。一个 const 右值引用在这里对你没有任何好处,因为你实际上不能离开它。 -
您使用的是哪种语言版本?由于强制复制省略,C++17 永远不会收到移动构造函数调用,我不希望您在任何启用了优化的编译器中看到这一点。我也不能reproduce this with gcc。
-
a是一个左值,默认情况下会调用复制构造函数。仅当使用std::move()将参数强制转换为右值引用时,才会调用移动构造函数。试试:std::make_shared<Node>(std::move(a));。此外,Node(const Node&& other)是定义移动构造函数的错误方法。使用Node(Node&& other) -
Apple Clang 是一种奇怪而可怕的野兽。考虑使用更普通的编译器,例如实际的 gcc 或实际的 clang。
标签: c++ function pointers smart-pointers shared