c++11 的新特性,shared_ptr 的正确使用?
New to c++11 features, proper use of shared_ptr?
所以我的理解是,当对象的最后一个剩余所有者被销毁或重新分配时,shared_ptr 会自动从内存中释放,(似乎好得令人难以置信?)并且当许多实例可能是共享同一个对象。正确吗?
所以在我的例子中,我正在制作一个 2d 平铺世界,所以我在屏幕上绘制了许多相同的纹理。
我有
std::map<int, shared_ptr<Tile>> Tiledb;
存储所有的瓷砖。我的想法是只加载一次纹理,然后我可以根据需要多次渲染它。然后一旦游戏结束我打电话给
Tiledb.clear();
这会自动释放所有内存吗?我已经习惯了常规的指示,以至于这看起来很神奇,而且坦率地说,太容易了。我认为这就是它的工作原理是错误的吗?使用 shared_ptrs 有什么缺点吗?我只是很惊讶这存在哈哈。
感谢您提供任何信息。
绝对。
Class 类型具有构造函数和析构函数。
它们在实例化期间和变量生命周期结束时被隐式调用。
这个概念被称为 RAII,智能指针利用它来进行自动内存管理。
这取决于您的用例,但您也可以考虑使用唯一指针:
#include <iostream>
#include <memory>
#include <map>
struct Foo{
Foo(){
std::cout << "construct\n";
}
~Foo(){
std::cout << "destruct\n";
}
};
int main(){
std::map<int, std::unique_ptr<Foo>> m;
//prints construct 3 times
m.emplace(1,std::make_unique<Foo>());
m.emplace(2,std::make_unique<Foo>());
m.emplace(3,std::make_unique<Foo>());
//prints destruct 3 times
m.clear();
}
...it's useful when many instances may be sharing the same object. Correct?
不完全是。当许多实例可能 拥有 同一个对象时,它很有用。共享不足以证明使用 std::shared_ptr
是合理的,因为使用它肯定会产生一些开销。
当您创建动态资源时,您需要考虑所有权 即。 谁负责删除它?负责删除资源的对象应该使用某种智能指针(或容器)来管理资源。
如果只有一个对象负责决定何时必须删除资源,则使用 std::unique_ptr
。如果其他 objects/functions 需要 share 访问资源但永远不会负责删除它,则向他们传递 reference 或指向资源的原始指针。
使用 std::shared_ptr
的时间是当您无法知道共享 资源的哪些对象将是需要删除它的对象时。在那种情况下,每个对象都应该通过持有 std::shared_ptr
.
来持有资源的 所有权
即使多个对象通过 std::shared_ptr
共享 所有权 他们仍然应该只传递 reference 或 原始指针指向objects/functions不需要所有权权利。
另一个问题是 std::stared_ptr
轮流随意(不需要它们的地方)是它们可能会遇到 Java 内存泄漏 问题.那就是对象永远不会消亡,因为对它们的一些引用仍然存在于软件的 forgotten 部分中。它们会逐渐积累并侵蚀你的记忆。
通常,您应该更喜欢将资源保存在 容器 中,例如 std::vector
或 std::map
:
std::map<int, Tile> Tiledb;
容器管理Tile
的销毁,因此不需要智能指针。
但是,如果您正在使用 多态 Tile
对象,那么您需要使用 指针 来存储它们。为此更喜欢使用 std::unique_ptr
:
// When the Tiles are no longer needed after the map is destroyed
std::map<int, std::unique_ptr<Tile>> Tiledb;
如果其他对象需要继续访问 Tile
对象 在 之后 map 被销毁然后 std::shared_ptr
可能合适:
// only when Tiles need to keep living after the map is destroyed.
std::map<int, std::shared_ptr<Tile>> Tiledb;
所以我的理解是,当对象的最后一个剩余所有者被销毁或重新分配时,shared_ptr 会自动从内存中释放,(似乎好得令人难以置信?)并且当许多实例可能是共享同一个对象。正确吗?
所以在我的例子中,我正在制作一个 2d 平铺世界,所以我在屏幕上绘制了许多相同的纹理。
我有
std::map<int, shared_ptr<Tile>> Tiledb;
存储所有的瓷砖。我的想法是只加载一次纹理,然后我可以根据需要多次渲染它。然后一旦游戏结束我打电话给
Tiledb.clear();
这会自动释放所有内存吗?我已经习惯了常规的指示,以至于这看起来很神奇,而且坦率地说,太容易了。我认为这就是它的工作原理是错误的吗?使用 shared_ptrs 有什么缺点吗?我只是很惊讶这存在哈哈。
感谢您提供任何信息。
绝对。
Class 类型具有构造函数和析构函数。
它们在实例化期间和变量生命周期结束时被隐式调用。
这个概念被称为 RAII,智能指针利用它来进行自动内存管理。
这取决于您的用例,但您也可以考虑使用唯一指针:
#include <iostream>
#include <memory>
#include <map>
struct Foo{
Foo(){
std::cout << "construct\n";
}
~Foo(){
std::cout << "destruct\n";
}
};
int main(){
std::map<int, std::unique_ptr<Foo>> m;
//prints construct 3 times
m.emplace(1,std::make_unique<Foo>());
m.emplace(2,std::make_unique<Foo>());
m.emplace(3,std::make_unique<Foo>());
//prints destruct 3 times
m.clear();
}
...it's useful when many instances may be sharing the same object. Correct?
不完全是。当许多实例可能 拥有 同一个对象时,它很有用。共享不足以证明使用 std::shared_ptr
是合理的,因为使用它肯定会产生一些开销。
当您创建动态资源时,您需要考虑所有权 即。 谁负责删除它?负责删除资源的对象应该使用某种智能指针(或容器)来管理资源。
如果只有一个对象负责决定何时必须删除资源,则使用 std::unique_ptr
。如果其他 objects/functions 需要 share 访问资源但永远不会负责删除它,则向他们传递 reference 或指向资源的原始指针。
使用 std::shared_ptr
的时间是当您无法知道共享 资源的哪些对象将是需要删除它的对象时。在那种情况下,每个对象都应该通过持有 std::shared_ptr
.
即使多个对象通过 std::shared_ptr
共享 所有权 他们仍然应该只传递 reference 或 原始指针指向objects/functions不需要所有权权利。
另一个问题是 std::stared_ptr
轮流随意(不需要它们的地方)是它们可能会遇到 Java 内存泄漏 问题.那就是对象永远不会消亡,因为对它们的一些引用仍然存在于软件的 forgotten 部分中。它们会逐渐积累并侵蚀你的记忆。
通常,您应该更喜欢将资源保存在 容器 中,例如 std::vector
或 std::map
:
std::map<int, Tile> Tiledb;
容器管理Tile
的销毁,因此不需要智能指针。
但是,如果您正在使用 多态 Tile
对象,那么您需要使用 指针 来存储它们。为此更喜欢使用 std::unique_ptr
:
// When the Tiles are no longer needed after the map is destroyed
std::map<int, std::unique_ptr<Tile>> Tiledb;
如果其他对象需要继续访问 Tile
对象 在 之后 map 被销毁然后 std::shared_ptr
可能合适:
// only when Tiles need to keep living after the map is destroyed.
std::map<int, std::shared_ptr<Tile>> Tiledb;