为什么make_shared会两次调用析构函数并复制构造函数?

时间:2014-05-15 23:22:53

标签: c++ constructor destructor shared-ptr copy-constructor

我正在改写一个旧项目的部分内容。我编写了一个Texture类,它从磁盘加载文件,并将数据存储为unsigned char的数组(使用外部库,因此使用vector<unsigned char> isn&#39 ;选项)。

main()中,我加载纹理并将其传递到Scene对象上。由于纹理可以很大并且可以在多个对象之间共享相同的纹理,因此在将它们传递给std::shared_ptr<Texture>之前创建一堆Scene

最初的问题是,Texture的析构函数会被调用两次并导致malloc抱怨释放的指针没有被分配(外部lib正在使用malloc,所以再次,它不在我的手中)。在打印到控制台进行一些调查后,似乎是通过复制构造函数复制纹理,然后立即销毁。我认为shared_ptr的意思是不复制对象,而是增加引用计数。

这是一个最小main(),我在其中创建了一个shared_ptr<Texture>

int main(int argc, char *argv[])
{
    std::shared_ptr<Texture> up(std::make_shared<Texture>("textures/lakeup.png"));
    return 0;
}

这是课程Texture

class Texture
{
public:
    Texture(const std::string&)
    {
        std::cout << "Texture::Texture() for " << this << std::endl;
    }

    Texture(const Texture& other)
    {
        std::cout << "Texture::Texture(const Texture&) for " << this << std::endl;
    }

    ~Texture()
    {
        std::cout << "Texture::~Texture() for " << this << std::endl;
    }
};

最后,这是此代码的控制台输出(更新为仅加载一个纹理):

Texture::Texture() for 0x7fff5fbff808
Texture::Texture(const Texture&) for 0x7fff5fbff820
Texture::Texture(const Texture&) for 0x608000043228
Texture::~Texture() for 0x7fff5fbff820
Texture::~Texture() for 0x7fff5fbff808
Texture::~Texture() for 0x608000043228

我很困惑为什么在make_shared之后立即调用复制构造函数,为什么不复制shared_ptr复制构造函数,这应该只增加引用计数。提前谢谢。

使用最小版本进行了更新。有趣的是,std::make_shared<Texture>()似乎无法使用0个参数,这就是为什么我会这样做的原因。暂时离开了std::string。我在函数make_shared_object.hpp的第711行收到了编译错误make_shared( A1 const & a1 )

我注意到的另一件事是将make_shared<Texture>("")替换为new Texture("")的行为符合预期:

Texture::Texture() for 0x60800022fd20
Texture::~Texture() for 0x60800022f640

它有效,但如果我离开而不理解make_shared实际上在做什么,那就不太令人满意了。

我正在使用XCode 5.1.1,它似乎对应于llvm / clang 5.1。

0 个答案:

没有答案