C ++ make_shared两次调用析构函数

时间:2018-11-28 20:59:49

标签: c++ shared-ptr

我有一些使我感到困惑的代码。我一直在学习有关shared_pointers的信息,并正在关注YouTube上的指南。我正在使用make_shared构造我的Dog,并将共享指针分配给p。

class Dog
{
    private:
        std::string name;
    public:
        Dog(std::string _name):
            name(_name)
        {
            std::cout << "Creating dog with name " << name << std::endl;
        }

        ~Dog() { std::cout << "Destroying dog!" << std::endl; }

        void bark()
        {
            std::cout << name << " barks like a Dog! Woof!" << std::endl;
        }
};

std::shared_ptr<Dog> foo()
{
    std::cout << "Entering foo" << std::endl;
    std::shared_ptr<Dog> p = std::make_shared<Dog>("Tank"); //will be deleted when freed off stack

    std::cout << "Dog use count = " << p.use_count() << std::endl;

    std::shared_ptr<Dog> p2 = p;

    std::cout << "Dog use count = " << p.use_count() << std::endl;

    std::cout << "Returning first pointer from foo!" << std::endl;
    return p;
}
int main()
{
    std::shared_ptr<Dog> p = foo();

    std::cout << "Dog use count = " << p.use_count() << std::endl;

    return 0;
}

编译为

g++ shared_ptr.cpp

但是,这是我的输出:

Entering foo
Creating dog with name Tank
Destroying dog!
Destroying dog!
Dog use count = 1
Dog use count = 2
Returning first pointer from foo!

有人可以解释构造的逻辑,然后以某种方式进行两次破坏吗?

1 个答案:

答案 0 :(得分:3)

我想我已经解决了。

我尝试使用

在centos上进行编译
g++ shared_ptr.cpp

但是编译器抱怨shared_ptr不是std的一部分。更改为

g++ -std=c++11 shared_ptr.cpp

使编译成功,并且我看到了我期望的行为(没有双重破坏)。

仅指定了我的Mac的makefile

g++ shared_ptr.cpp

我在Mac上检查了默认的c标准,并将其设置为199711L(1997ish)。即使这不是c ++ 11,也可以编译,尽管行为显然很奇怪。

在centOS上,默认标准也是199711L,但是编译失败。听起来这是不确定的行为,非常危险。