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

C++ make_shared calling destructor twice

我有一些代码让我感到困惑。我一直在学习 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!

谁能解释一下构造然后双重破坏的逻辑?

我想我已经弄明白了。

我尝试在 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上,默认std也是199711L,但是编译失败。听起来这是未定义的行为,非常危险。