std::shared#ptr数组在C++;作品 我是C++初学者,学习智能指针和继承。我有一个基类Shape(抽象),作为派生类,我有三角形、等腰和等边
我的想法是根据指向基类的类型为每个类打印适当的打印消息,我在main()中声明了基类,如下所示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
#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的输出是错误的。