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 的知识之前,您需要掌握构建和销毁的顺序。
我是一名 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 的知识之前,您需要掌握构建和销毁的顺序。