带有删除程序类的 shared_ptr - 为什么要复制删除程序?

klk*_*206 7 c++ copy-constructor shared-ptr

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

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());
}
Run Code Online (Sandbox Code Playgroud)

我看到,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
Run Code Online (Sandbox Code Playgroud)

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

j6t*_*j6t 0

删除器通常是一个带有operator(). 在优化的代码和编写良好的 实现中shared_ptr,作为空类的删除器不占用空间,因此复制开销为零。

实现通常知道优化器完成工作后复制对象是否昂贵以及是否必须采取预防措施。

在所呈现的案例中,我猜您正在观察一个未优化的构建。您将看到实现如何通过多层函数调用传递删除器。D在优化的构建中,由于删除器类为空,因此实际上不会复制任何内容。