C++中std::shared_ptr数组的工作原理

How the array of std::shared_ptr in C++ works

我是一名 C++ 初学者,正在学习智能指针和继承。我有一个底数 class Shape(抽象)和派生的 classes 我有三角形、等腰和等边。

我的想法是根据指向基 class 的类型为每个 class 打印适当的打印消息,我已经在 main() 中声明了它,如下所示。

#include <iostream>
#include <memory>

class Shape
{
public:
    virtual const void triangle()const = 0;
    virtual ~Shape(){ std::cout<<"Shape Deleted\n";  }
};

class Triangle: public Shape
{
public:
    virtual const void triangle()const override
    { std::cout<<"I am a triangle\n";   }
    virtual ~Triangle(){ std::cout<<"Triangle Deleted\n";   }
};

class Isosceles : public Triangle
{
public:
    virtual const void triangle()const override
    {   std::cout<<"I am an isosceles triangle\n";  }
    virtual ~Isosceles(){ std::cout<<"Isosceles Deleted\n";   }
};
class Equilateral: public Isosceles
{
public:
    virtual const void triangle()const override
    {   std::cout<<"I am an equilateral triangle\n";  }
    virtual ~Equilateral(){ std::cout<<"Equilateral Deleted\n";   }
};

当我使用传统方法使用 new 关键字创建指针对象时,所有 classes 的析构函数都能完美运行(输出如下所示)。 main() 是:

int main()
{
    Shape *Obj[3];
    Obj[0] = new Equilateral();
    Obj[1] = new Isosceles();
    Obj[2] = new Triangle();

    for(auto it: Obj)
        it->triangle();

    delete Obj[0];
    return 0;
}

The output is here

但是当我改成std::shared_ptr时,事情就不同了,我无法理解。 main() 是:

int main()
{
    std::shared_ptr<Shape> obj[3];

    obj[0] = std::make_shared<Equilateral>();
    obj[1] = std::make_shared<Isosceles>();
    obj[2] = std::make_shared<Triangle>();

    for(auto it: obj)
        it->triangle();

    return 0;
}

The Output Now:

谁能帮我弄明白,为什么会这样? 可能会提前致谢。

当您使用原始指针时,您只会破坏第一个对象:

delete Obj[0];

并使其他 2 个泄漏,而当您使用 std::shared_ptr 时,所有 3 个对象都已正确清洁。这就是为什么推荐使用智能指针的确切原因。

实际上你的第二个片段是正确的,输出完全符合预期。 你的第一个片段有一个错误:你只是 delete obj[0];obj[1]obj[2] 呢?如果删除数组的所有成员,您会发现两个代码示例的输出之间的差异消失了。 智能指针的好处是它们应该在 "fire-and-forget" 庄园中使用。

最后,请更加谨慎地阅读您的那本书:在开始任何有关 OOP 的知识之前,您需要掌握构建和销毁的顺序。