[this问题的跟进]

最近,我一直在处理指向c样式数组的智能指针。我最终做了最后的建议,而是使用智能指针指向 vector ,但是在此期间,我得到了一些建议:不要使用shared_ptr<T>对象来管理最初由make_unique<T[]>构成的数组,因为它不会调用delete[]而是delete

这对我来说似乎不合逻辑,我同时检查了Coliru和Standard:

这段代码:

#include <iostream>
#include <memory>

int main()
{
    std::cout << "start!\n";
    auto customArrayAllocator = [](unsigned int num){
        std::cout << "custom array allocator\n";
        return new int[num];
    };

    std::cout << "allocator constructed\n";

    auto customArrayDeleter = [](int *ptr){
        std::cout << "custom array deleter\n";
        delete[] ptr;
    };

    std::cout << "deleter constructed\n";

    std::unique_ptr<int[], decltype(customArrayDeleter)>
        myUnique(customArrayAllocator(4), customArrayDeleter);

    std::cout << "unique_ptr constructed\n";

    std::shared_ptr<int>
        myShared = std::move(myUnique);

    std::cout << "shared_ptr constructed\n";
}

产生以下输出:
start!
allocator constructed
deleter constructed
custom array allocator
unique_ptr constructed
shared_ptr constructed
custom array deleter

如我所料,这似乎表明unique_ptr<T[]>的删除程序已传递给shared_ptr<T>

根据C++ 14标准§20.8.2.2.1 pg. 571 of doc, 585 of pdf



如果我没看错,那意味着shared_ptr对象从unique_ptr的指针和删除器构造自己。此外,根据我对原始问题的回答,我的理解是::pointerunique_ptr<T[]>类型为T*,应将其转换为shared_ptr<T>::pointerT*。因此,删除器应该只是从unique_ptr对象中复制出来的,对吗?

我的测试是否仅因为它实际上不等于std::make_shared<T[]>的功能而起作用,还是语法
std::shared_ptr<T> mySharedArray = std::make_unique<T[]>(16);

一个很好的,异常安全(且更清洁)的替代品
std::shared_ptr<T> mysharedArray(new T[16], [](T* ptr){delete[] ptr;});

和它的同类,当我无法使用Boost的shared array并希望避免在我的代码中包含vectorarray header 时?

最佳答案

是的,由于您陈述的原因,您的示例是有效的。 unique_ptr::pointerint *,并且您正尝试将其所有权传递给shared_ptr<int>,因此您列出的转换构造函数将参与重载解析,并且将创建删除器的拷贝(std::default_delete<int[]>),因为它不是引用类型。

因此,以下内容有效,并且在delete[]引用计数变为零时将调用shared_ptr

std::shared_ptr<T> mySharedArray = std::make_unique<T[]>(16);

除了显示的lambda之外,另一种写方法是
std::shared_ptr<T> mySharedArray(new T[16], std::default_delete<int[]>());

这将导致mySharedArray获取与上一行相同的删除器。

关于c++ - 从unique_ptr <T []>初始化shared_ptr <T>,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/30495941/

10-10 09:12