首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >在运行构造函数之前,shared_ptr a= make_shared()是否创建shared_ptr的副本?

在运行构造函数之前,shared_ptr a= make_shared()是否创建shared_ptr的副本?
EN

Stack Overflow用户
提问于 2022-03-19 08:45:28
回答 1查看 376关注 0票数 0

这可能是个愚蠢的问题。

假设我们在C++11域,我们使用make_shared()创建一个智能指针。然后,我们使用这个智能指针初始化一个变量,如下所示:

代码语言:javascript
复制
std::shared_ptr<class> = make_shared(/* args to c'tor of class*/ );

现在我知道两件事:

  1. 分配不是初始化。在这种情况下,我们有初始化。这意味着在上述情况下,可能会为make_shared.
  2. Copy省略返回的shared_ptr调用副本构造函数,这在C++17.

中是强制性的。

这是否意味着在make_shared的每个实例中都会创建shared_ptr的临时副本并将其插入副本构造函数中?因为这意味着线程安全,如果其他线程抢占线程并调用shared_ptr::use_count()成员函数,则必须在初始化过程中执行锁。

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2022-03-19 15:00:20

有两件事可以避免复制:

optimization);

  • 2 1是编译器的RVO (返回值constructor/assignment.

  • )

对于代码auto foo = std::make_shared<Foo>();,RVO将直接在堆栈上创建对象。即使我们通过-fno-elide-constructors禁用RVO,移动构造函数也会尝试使用,因为从make_shared返回的对象是临时的。

下面是一个简单的测试代码。(这段代码只显示了概念,而不是真实世界的shared_ptr实现)

代码语言:javascript
复制
#include <iostream>

template <typename T>
struct my_shared_ptr
{
    T *t_{nullptr};

    my_shared_ptr(T *t): t_(t) {
        std::cout << "constructor" << std::endl;
    };

    my_shared_ptr(const my_shared_ptr<T>&) {
        std::cout << "copy" << std::endl;
    }

    my_shared_ptr<T>& operator=(const my_shared_ptr<T>&) {
        std::cout << "copy" << std::endl;
        return *this;
    }

#ifndef NO_MOVE
    my_shared_ptr(my_shared_ptr<T>&&) {
        std::cout << "move" << std::endl;
    }

    my_shared_ptr<T>& operator=(my_shared_ptr<T>&&) {
        std::cout << "move" << std::endl;
        return *this;
    }
#endif
};

template <typename T>
my_shared_ptr<T>
my_make_shared() {
    return my_shared_ptr<T>(new T);
}

struct Foo {};

int main()
{
    auto foo = my_make_shared<Foo>();
    return 0;
}

使用c++11编译的条件1显示:

代码语言:javascript
复制
$ g++ a.cc -std=c++11 ; ./a.out
constructor

使用c++11/禁用RVO编译的条件2显示:

代码语言:javascript
复制
$ g++ a.cc -std=c++11 -fno-elide-constructors ; ./a.out
constructor
move
move

条件3,使用c++11/禁用RVO/no move编译显示:

代码语言:javascript
复制
$ g++ a.cc -std=c++11 -fno-elide-constructors -DNO_MOVE ; ./a.out
constructor
copy
copy
票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/71536672

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档