std::shared#ptr数组在C++;作品 我是C++初学者,学习智能指针和继承。我有一个基类Shape(抽象),作为派生类,我有三角形、等腰和等边

std::shared#ptr数组在C++;作品 我是C++初学者,学习智能指针和继承。我有一个基类Shape(抽象),作为派生类,我有三角形、等腰和等边,c++,polymorphism,smart-pointers,C++,Polymorphism,Smart Pointers,我的想法是根据指向基类的类型为每个类打印适当的打印消息,我在main()中声明了基类,如下所示 #include <iostream> #include <memory> class Shape { public: virtual const void triangle()const = 0; virtual ~Shape(){ std::cout<<"Shape Deleted\n"; } }; class Triangle: publ

我的想法是根据指向基类的类型为每个类打印适当的打印消息,我在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";   }
};

但是当我换成std::shared_ptr时,事情就不同了,我无法理解。
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;
}
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;
}
intmain()
{
std::shared_ptr obj[3];
obj[0]=std::make_shared();
obj[1]=std::make_shared();
obj[2]=std::make_shared();
用于(自动it:obj)
它->三角形();
返回0;
}

有谁能帮我弄清楚,为什么会这样?
请提前感谢。

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

delete Obj[0];

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

实际上,您的第二个代码段是正确的,并且输出完全符合预期。 您的第一个代码片段有一个bug:您只需
删除obj[0]。那么
obj[1]
obj[2]
呢?如果删除数组的所有成员,将看到两个代码示例的输出之间的差异消失。 智能指针的好处在于,它们应该被用于“失火而忘却”的庄园


最后,请更加小心地阅读您的那本书:在开始OOP之前,您需要掌握构造和销毁的顺序。

使用原始指针数组,您实际上不会删除
obj[1]
obj[2]
。这似乎只是因为
obj[0]
需要调用它的每个基类型的析构函数;它们根本没有被销毁。你不能做
delete[]Obj因为未动态分配
Obj
。即使是这样,删除指针数组也不会删除指针指向的每个元素。你需要一个一个地删除每一个元素。为什么你会感到困惑?在第一个示例中,手动删除单个对象,并通过继承链调用所有析构函数。在第二种情况下,
shared\u ptr
为所有3个元素调用析构函数。对于数组的每个元素,我创建它的所有基类。删除时间也需要分别删除。我错认为shared_ptr的输出是错误的。那么智能指针的输出是正确的吗?为什么每次删除时都会删除shape或其他类?@Kallan这两个输出都是正确的,因为在给定代码的情况下,它们会执行预期的操作。因为从大多数派生对象到基对象的层次链都会调用析构函数。是的,现在我知道了。对于数组的每个元素,我创建它的所有基类。删除时间也需要分别删除。我错误地认为共享ptr的输出是错误的。