c++ - 带有删除器类的shared_ptr - 为什么删除器被复制?

标签 c++ shared-ptr copy-constructor

假设我使用自定义删除器创建一个共享指针。在下面的代码中,我想检查删除器对象本身会发生什么:

struct A {
    A() { std::cout << "A\n"; }
    ~A() { std::cout << "~A\n"; }
};

struct D {
    D() {
        std::cout << "D\n";
    }
    ~D() {
        std::cout << "~D\n";
    }
    D(const D&) {
        std::cout << "D(D&)\n";
    }
    void operator()(A* p) const {
        std::cout << "D(foo)\n";
        delete p;
    }
};

int main()
{
    std::shared_ptr<A> p(new A, D());
}

我看到“deleter”类的 D(const D&)~D() 又被调用了六次:

D
A
D(D&)
D(D&)
D(D&)
D(D&)
D(D&)
D(D&)
~D
~D
~D
~D
~D
~D
D(foo)
~A
~D

会发生什么?为什么需要复制这么多次?

最佳答案

我用 gcc 7.4 检查了你的代码,我得到了相同数量的析构函数调用。您观察到删除器对象通过 std::move(deleter) 移动了六次。

当您向类添加析构函数时,默认移动语义的自动生成将被禁用,您需要显式定义它们:

D(D&&) = default;
D& operator=(D&&) = default;

但是,即使使用移动语义,析构函数仍然可以被调用最多六次。

关于c++ - 带有删除器类的shared_ptr - 为什么删除器被复制?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/59385168/

相关文章:

c++ - 枚举数组作为参数 c++

c++ - 为什么删除 End-Iterator 不会导致 Segmentation Fault with shared_ptr?

c++ - 为什么用户定义的复制构造函数调用基本构造函数,而默认复制构造函数则不调用?

c++ - 同一容器中的共享指针和原始指针

templates - 关于 postblit 和 move 语义的问题

c++ - 复制构造函数错误 : returning a value from a constructor

c++ - 将包含另一个 vector 的结构 vector 写入二进制文件

c++ - 是否有一些类似于 boost program_options 但用于 *keyboard shortcut auto-gen help* 的 c++ 库/源代码?

C++ 文件内存映射容器类似于 std::vector/boost::array

C++:修改 shared_ptr 元素的 vector