标签: smart-pointers

shared_ptr魔术:)

Lidström先生和我有一个争论 :)

Lidström先生的主张是,构造shared_ptr<Base> p(new Derived);不要求Base有虚拟析构函数:

Armen Tsirunyan:"真的吗?shared_ptr会正确清理吗?在这种情况下你能否证明可以实现这种效果?"

DanielLidström:" shared_ptr使用自己的析构函数来删除Concrete实例.这在C++社区中被称为RAII.我的建议是你学习RAII的全部内容.它将使你的C++编码在使用时更加容易RAII在所有情况下."

Armen Tsirunyan:"我知道RAII,我也知道,当pn达到0时,最终shared_ptr析构函数可能会删除存储的px.但是如果px有静态类型指针Base和动态类型指针Derived,那么除非Base有一个虚拟析构函数,会导致不确定的行为.如果我错了,请纠正我."

DanielLidström:" shared_ptr知道静态类型是Concrete.它知道这个,因为我在它的构造函数中传递它!看起来有点像魔术,但我可以向你保证它是设计上的并且非常好."

所以,判断我们.如何实现shared_ptr而不需要多态类具有虚拟析构函数是否可能(如果是)?提前致谢

c++ destructor smart-pointers

82
推荐指数
3
解决办法
1万
查看次数

使用shared_ptr的示例?

嗨,我今天问了一个问题,关于如何在同一个向量数组中插入不同类型的对象,我的代码就是那个问题

 gate* G[1000];
G[0] = new ANDgate() ;
G[1] = new ORgate;
//gate is a class inherited by ANDgate and ORgate classes
class gate
{
 .....
 ......
 virtual void Run()
   {   //A virtual function
   }
};
class ANDgate :public gate 
  {.....
   .......
   void Run()
   {
    //AND version of Run
   }  

};
 class ORgate :public gate 
  {.....
   .......
   void Run()
   {
    //OR version of Run
   }  

};      
//Running the simulator using overloading concept
 for(...;...;..)
 {
  G[i]->Run() ;  //will run …
Run Code Online (Sandbox Code Playgroud)

c++ boost smart-pointers vector shared-ptr

81
推荐指数
3
解决办法
16万
查看次数

auto_ptr是否已被弃用?

  1. 在传入的C++标准中是否会弃用auto_ptr?
  2. unique_ptr应该用于所有权转移而不是shared_ptr吗?
  3. 如果unique_ptr不在标准中,那么我是否需要使用shared_ptr?

c++ standards smart-pointers auto-ptr unique-ptr

77
推荐指数
3
解决办法
4万
查看次数

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

shared_ptr派生类型传递给采用shared_ptr基类型的函数的最佳方法是什么?

我通常通过shared_ptr引用传递s以避免不必要的副本:

int foo(const shared_ptr<bar>& ptr);
Run Code Online (Sandbox Code Playgroud)

但如果我尝试做类似的事情,这不起作用

int foo(const shared_ptr<Base>& ptr);

...

shared_ptr<Derived> bar = make_shared<Derived>();
foo(bar);
Run Code Online (Sandbox Code Playgroud)

我可以用

foo(dynamic_pointer_cast<Base, Derived>(bar));
Run Code Online (Sandbox Code Playgroud)

但这似乎是次优的,原因有两个:

  • dynamic_cast对于简单的派生到基础演员来说,A 似乎有点过分.
  • 据我了解,dynamic_pointer_cast创建一个指向传递给函数的副本(虽然是临时的).

有更好的解决方案吗?

后人更新:

原来这是一个缺少头文件的问题.此外,我在这里尝试做的是一个反模式.通常,

  • 不影响对象生命周期的函数(即对象在函数持续时间内保持有效)应采用普通引用或指针,例如int foo(bar& b).

  • 使用对象的函数(即,是给定对象的最终用户)应该采用unique_ptrby值,例如int foo(unique_ptr<bar> b).std::move调用者应该将值放入函数中.

  • 延长对象生命周期的函数应采用shared_ptrby值,例如int foo(shared_ptr<bar> b).避免循环引用的通常建议适用.

有关详细信息,请参阅Herb Sutter的回归基础讲座.

c++ casting smart-pointers shared-ptr c++11

74
推荐指数
4
解决办法
5万
查看次数

RAII与垃圾收集器

我最近在CppCon 2016上观看了Herb Sutter关于"Leak Free C++ ..."的精彩演讲,他谈到了使用智能指针实现RAII(资源获取是初始化) - 概念以及它们如何解决大多数内存泄漏问题.

现在我在想.如果我严格遵循RAII规则,这似乎是一件好事,为什么这与C++中的垃圾收集器有什么不同呢?我知道使用RAII,程序员可以完全控制何时再次释放资源,但是在任何情况下都只对垃圾收集器有益吗?它的效率真​​的会降低吗?我甚至听说有一个垃圾收集器可以更高效,因为它可以一次释放更大的内存块,而不是在代码中释放小内存块.

c++ garbage-collection memory-leaks smart-pointers

74
推荐指数
9
解决办法
8577
查看次数

何时使用shared_ptr以及何时使用原始指针?

class B;

class A
{
public:
    A ()
        : m_b(new B())
    {
    }

    shared_ptr<B> GimmeB ()
    {
        return m_b;
    }

private:
    shared_ptr<B> m_b;
};
Run Code Online (Sandbox Code Playgroud)

假设B是一个在语义上不应该存在于A的生命周期之外的类,也就是说,B对于它自身存在完全没有意义.应该GimmeB退还shared_ptr<B>还是B*

一般来说,完全避免在C++代码中使用原始指针代替智能指针是一种好习惯吗?

我认为shared_ptr只应该在有明确的转让或共享所有权的情况下使用,我认为在函数分配一些内存,用一些数据填充并返回它的情况下很少见,并且有理解在调用者和被调用者之间,前者现在对该数据"负责".

c++ smart-pointers

73
推荐指数
4
解决办法
4万
查看次数

如何使用带有智能指针的协变返回类型?

我有这样的代码:

class RetInterface {...}

class Ret1: public RetInterface {...}

class AInterface
{
  public:
     virtual boost::shared_ptr<RetInterface> get_r() const = 0;
     ...
};

class A1: public AInterface
{
  public:
     boost::shared_ptr<Ret1> get_r() const {...}
     ...
};
Run Code Online (Sandbox Code Playgroud)

此代码无法编译.

在视觉工作室,它提出

C2555:覆盖虚函数返回类型不同且不协变

如果我不使用boost::shared_ptr但返回原始指针,代码编译(我理解这是由于C++中的协变返回类型).我可以看到这个问题是因为boost::shared_ptrRet1不是源自boost::shared_ptrRetInterface.但我想返回boost::shared_ptrRet1在其他类使用,否则我必须在返回后投返回值.

  1. 难道我做错了什么?
  2. 如果没有,为什么这样的语言 - 它应该是可扩展的,以处理这种情况下智能指针之间的转换?有一个理想的解决方法吗?

c++ smart-pointers covariance

63
推荐指数
2
解决办法
1万
查看次数

我应该分配还是重置unique_ptr?

鉴于自有对象的生命周期与其所有者链接的常见情况,我可以使用两种方式之一的唯一指针..

它可以分配:

class owner
{
    std::unique_ptr<someObject> owned;    
public:
    owner()
    {
        owned=std::unique_ptr<someObject>(new someObject());        
    }
};
Run Code Online (Sandbox Code Playgroud)

可以使用重置方法:

class owner
{
    std::unique_ptr<someObject> owned;    
public:
    owner()
    {
        owned.reset(new someObject());
    }
};
Run Code Online (Sandbox Code Playgroud)

为了最佳实践,我应该更喜欢一种形式吗?

编辑:对不起伙计们.我简化了这个.堆分配发生在初始化方法中,而不是在ctor中.因此,我无法使用初始化列表.

c++ smart-pointers unique-ptr c++11

62
推荐指数
2
解决办法
4万
查看次数

为什么unique_ptr将删除器作为类型参数而shared_ptr没有?

std::unique_ptr模板有两个参数:指针对象的类型和删除器的类型.第二个参数有一个默认值,所以你通常只写一些像std::unique_ptr<int>.

std::shared_ptr模板有虽然只有一个参数:指针对象的类型.但是你也可以使用自定义删除器,即使删除类型不在类模板中.通常的实现使用类型擦除技术来执行此操作.

有没有理由不使用相同的想法std::unique_ptr

c++ smart-pointers type-erasure

60
推荐指数
1
解决办法
3755
查看次数

C++ 11:用std :: shared_ptr()替换所有非拥有的原始指针?

随着它的出现std::unique_ptr,瑕疵std::auto_ptr最终可以得到休息.所以在过去的几天里,我一直在改变我的代码以使用智能指针并delete从我的代码中消除所有代码.

虽然valgrind说我的代码是内存清晰的,但智能指针的语义丰富性将使代码更清晰,更易于理解.

在大多数代码中,转换很简单:std::unique_ptr用于代替拥有对象持有的原始指针,抛弃delete,仔细撒取get(),reset()move()根据需要调用,以便与其余代码良好地连接.

我现在正在将非拥有原始指针转换为智能指针.

由于我小心对象的生命周期(我确保我的模块只依赖于一个方向),valgrind告诉我,我没有任何未初始化的读取,悬空指针或泄漏.所以,从技术上讲,我现在可以单独留下那些非拥有的原始指针.

但是,一种选择是将那些非拥有的原始指针更改为,std::shared_ptr因为我知道它们是非循环的.或者,将它们留作原始指针会更好吗?

我需要智能指针的资深用户提供一些建议,告诉你使用什么经验法则来决定是否保留非拥有的原始指针,或将它们翻译成std::shared_ptr,请记住我经常进行单元测试和valgrind我的码.

编辑:我可能误解了它的使用std::shared_ptr- 它们是否可以结合使用std::unique_ptr,或者如果我使用的话std::shared_ptr,所有句柄也应该是这样的情况std::shared_ptr

c++ memory smart-pointers c++11

57
推荐指数
3
解决办法
2万
查看次数