Tag: 智能指针

智能指针/ C安全内存pipe理?

我和其他许多人使用智能指针在C ++中使用诸如RAII等这样的东西来包装不安全的内存操作,取得了巨大的成功。 但是,如果有析构函数,类,操作符重载等,则包装内存pipe理更容易实现。 对于使用原始C99编写的程序,您可以在哪里指出(无意双关)来帮助安全的内存pipe理? 谢谢。

C ++ 11智能指针语义

我已经使用了几年的指针,但是我最近才决定转换到C ++ 11的智能指针(即独特,共享和弱)。 我对它们做了一些相当的研究,这些是我绘制的结论: 独特的指针是伟大的。 他们pipe理自己的记忆,并像原始指针一样轻量级。 尽可能优先于原始指针的unique_ptr。 共享指针是复杂的。 由于引用计数,它们有很大的开销。 通过const引用传递它们,或者遗憾你的方法的错误。 他们不是邪恶的,但应该谨慎使用。 共享指针应该拥有自己的对象; 当不需要所有权时使用弱指针。 locking一个weak_ptr具有与shared_ptr拷贝构造函数相同的开销。 继续忽略auto_ptr的存在,现在已经废弃了。 所以,考虑到这些原则,我着手修改我的代码库,以利用我们新的shiny的智能指针,完全打算尽可能多地指明原始指针。 然而,我很困惑,关于如何最好地利用C ++ 11智能指针。 举个例子,假设我们正在devise一个简单的游戏。 我们决定将一个虚构的Texture数据types加载到一个TextureManager类中是最佳的。 这些纹理是复杂的,所以将它们按价值传递是不可行的。 此外,让我们假设游戏对象需要特定的纹理,取决于它们的对象types(即汽车,船等)。 在此之前,我会将纹理加载到一个向量(或者像unordered_map这样的其他容器)中,并在每个相应的游戏对象中存储指向这些纹理的指针,以便在需要渲染时可以引用它们。 我们假设纹理保证比他们的指针长。 那么我的问题就是如何在这种情况下最好地利用智能指针。 我看到几个选项: 将纹理直接存储在容器中,然后在每个游戏对象中构造一个unique_ptr。 class TextureManager { public: const Texture& texture(const std::string& key) const { return textures_.at(key); } private: std::unordered_map<std::string, Texture> textures_; }; class GameObject { public: void set_texture(const Texture& texture) […]

Google可以使用智能指针返回types吗?

我有一个工厂,返回一个智能指针。 无论使用什么智能指针,我都无法让Google Mock嘲笑工厂方法。 模拟对象是所有方法都是虚拟的纯抽象接口的实现。 我有一个原型: MOCK_METHOD0(Create, std::unique_ptr<IMyObjectThing>()); 我得到: "…gmock/gmock-spec-builders.h(1314): error C2248: 'std::unique_ptr<_Ty>::unique_ptr' : cannot access private member declared in class 'std::unique_ptr<_Ty>'" 智能指针指向的types被定义。 而我得到它试图访问其中一个构造函数声明为private,但我不明白为什么。 当这是一个std :: auto_ptr,错误说没有复制构造函数,这使我困惑。 无论如何,有没有办法模拟一个方法,返回一个智能指针? 还是有更好的方法来build造一个工厂? 是我唯一的决心返回一个原始指针(blech …)? 我的环境是Visual Studio 2010 Ultimate和Windows 7.我没有使用CLI。

与C ++中的普通指针相比,智能指针的开销是多less?

与C ++ 11中的普通指针相比,智能指针的开销是多less? 换句话说,如果我使用智能指针,我的代码会变慢,如果是这样,慢多less? 具体来说,我问的是C ++ 11 std::shared_ptr和std::unique_ptr 。 显然,按下堆栈的东西会更大(至less我是这么认为的),因为一个智能指针还需要存储其内部状态(引用计数等),问题实际上是,这是多less影响我的performance,如果有的话? 例如,我从一个函数而不是一个普通的指针返回一个智能指针: std::shared_ptr<const Value> getValue(); // versus const Value *getValue(); 或者,例如,当我的一个函数接受一个智能指针作为参数,而不是一个正常的指针: void setValue(std::shared_ptr<const Value> val); // versus void setValue(const Value *val);

为什么unique_ptr实例化比原始指针更大的二进制编译?

我总是觉得std::unique_ptr与使用原始指针相比没有开销。 但是,编译下面的代码 #include <memory> void raw_pointer() { int* p = new int[100]; delete[] p; } void smart_pointer() { auto p = std::make_unique<int[]>(100); } 用g++ -std=c++14 -O3产生下面的程序集: raw_pointer(): sub rsp, 8 mov edi, 400 call operator new[](unsigned long) add rsp, 8 mov rdi, rax jmp operator delete[](void*) smart_pointer(): sub rsp, 8 mov edi, 400 call operator […]

什么时候应该使用智能指针上的原始指针?

看完这个答案之后 ,看起来最好尽可能地使用智能指针 ,并将“正常”/原始指针的使用量降到最低。 真的吗?

从shared_ptr获得正常的ptr?

我有类似于shared_ptr<Type> t(makeSomething(), mem_fun(&Type::deleteMe))我现在需要调用C风格的函数,需要一个指向Type的指针。 我如何从shared_ptr获取它?

将shared_ptr <Derived>作为shared_ptr <Base>传递

将派生types的shared_ptr传递给带有基types的shared_ptr的函数,最好的方法是什么? 我通常通过引用传递shared_ptr以避免不必要的副本: int foo(const shared_ptr<bar>& ptr); 但如果我尝试做类似的事情,这是行不通的 int foo(const shared_ptr<Base>& ptr); … shared_ptr<Derived> bar = make_shared<Derived>(); foo(bar); 我可以使用 foo(dynamic_pointer_cast<Base, Derived>(bar)); 但这似乎是次优的有两个原因: dynamic_cast对于简单的派生到基础的演员似乎有点过分。 据我所知, dynamic_pointer_cast创build一个副本(尽pipe是临时的)传递给函数的指针。 有更好的解决scheme吗? 后人更新: 原来是一个缺less头文件的问题。 另外,我在这里试图做的是被认为是反模式。 通常, 不影响对象的生命周期(即对象在函数期间保持有效的函数)的函数应该使用一个普通的引用或指针,例如int foo(bar& b) 。 使用一个对象的函数(即给定对象的最终用户)应该通过值来获取unique_ptr ,例如int foo(unique_ptr<bar> b) 。 调用者应该std::move值移入该函数。 延长对象生命周期的函数应该通过值来获取shared_ptr ,例如int foo(shared_ptr<bar> b) 。 避免循环引用的通常build议适用。 详情请参阅Herb Sutter的“ 回归基础” 。

从unique_ptr创build一个shared_ptr

在我最近回顾的一段代码中,用g++-4.6编译得很好,我遇到了一个奇怪的尝试,从std::unique_ptr创build一个std::shared_ptr : std::unique_ptr<Foo> foo… std::make_shared<Foo>(std::move(foo)); 这对我来说似乎很奇怪。 这应该是std::shared_ptr<Foo>(std::move(foo)); afaik,虽然我不完全熟悉的动作(我知道std::move只是一个演员,没有得到移动)。 使用此SSC上的不同编译器进行检查(NUC *)E #include <memory> int main() { std::unique_ptr<int> foo(new int); std::make_shared<int>(std::move(foo)); } 汇编结果: g ++ – 4.4.7给出编译错误 g ++ – 4.6.4编译没有任何错误 g ++ – 4.7.3给出了内部编译器错误 g ++ – 4.8.1给出了编译错误 铿锵声++ – 3.2.1编译没有任何错误 所以问题是:哪个编译器在标准方面是正确的? 标准是否要求这是一个无效的陈述,一个有效的陈述,或者这只是未定义的? 加成 我们已经同意,其中一些编译器(如clang ++和g ++ – 4.6.4)允许转换,而不应该转换。 然而,使用g ++ – 4.7.3(它在std::make_shared<Foo>(std::move(foo)); )上产生内部编译器错误,正确地拒绝了int bar(std::move(foo)); 由于这种巨大的行为差异,我将这个问题保持原样,尽pipe其中的一部分可以通过减lessint […]

将unique_ptr传递给函数

我试图“现代化”一些现有的代码。 我有一个类,目前有一个成员variables“设备*设备_”。 它使用new在某些初始化代码中创build一个实例,并在结构中有一个“delete device_”。 这个类的成员函数调用许多其他的以Device *为参数的函数。 这很好,但为了“代码化”我想我应该改变variables定义为"std::unique_ptr<Device> device_"并删除显式调用删除,这使得代码更安全,通常更好。 我的问题是这个 – 那么我应该如何将设备 _variables传递给所有需要它作为参数的函数呢? 我可以调用.get来获取每个函数调用中的原始指针。 但是,这似乎是丑陋的,浪费了一些使用unique_ptr的原因。 或者我可以改变每一个函数,而不是采取“Device *”types的参数,现在它需要一个types为“std :: unique_ptr&”的参数。 哪(对我)有点混淆函数原型,并使他们难以阅读。 这个最好的做法是什么? 我错过了其他select吗?