使用shared_ptr的示例?

Ahm*_*med 81 c++ boost smart-pointers vector 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 perfectly the right Run for the right Gate type
 } 
Run Code Online (Sandbox Code Playgroud)

我想使用载体,所以有人写道我应该这样做:

std::vector<gate*> G;
G.push_back(new ANDgate); 
G.push_back(new ORgate);
for(unsigned i=0;i<G.size();++i)
{
  G[i]->Run();
}
Run Code Online (Sandbox Code Playgroud)

但后来他和其他许多人建议我最好使用Boost指针容器
shared_ptr.我花了最近3个小时阅读这个主题,但文档对我来说似乎很先进.****任何人都可以给我一个小代码的shared_ptr使用示例以及他们建议使用的原因shared_ptr.也有其他类型,如ptr_vector,ptr_listptr_deque****

Edit1:我也读过一个代码示例,其中包括:

typedef boost::shared_ptr<Foo> FooPtr;
.......
int main()
{
  std::vector<FooPtr>         foo_vector;
........
FooPtr foo_ptr( new Foo( 2 ) );
  foo_vector.push_back( foo_ptr );
...........
}
Run Code Online (Sandbox Code Playgroud)

我不懂语法!

D.S*_*ley 114

使用vectorshared_ptr消除泄漏内存,因为你忘了走路载体和调用的可能性delete每个元素.让我们逐行浏览一个稍微修改过的示例版本.

typedef boost::shared_ptr<gate> gate_ptr;
Run Code Online (Sandbox Code Playgroud)

为共享指针类型创建别名.这避免了C++语言中的丑陋,这种丑陋是由于输入std::vector<boost::shared_ptr<gate> >而忘记了关闭大于号之间的空间.

    std::vector<gate_ptr> vec;
Run Code Online (Sandbox Code Playgroud)

创建一个空的矢量boost::shared_ptr<gate>对象.

    gate_ptr ptr(new ANDgate);
Run Code Online (Sandbox Code Playgroud)

分配一个新ANDgate实例并将其存储到一个shared_ptr.单独执行此操作的原因是为了防止操作抛出时可能发生的问题.在这个例子中这是不可能的.该升压shared_ptr"最佳实践"解释了为什么这是一个最好的做法来分配到一个独立的对象,而不是暂时的.

    vec.push_back(ptr);
Run Code Online (Sandbox Code Playgroud)

这将在向量中创建一个新的共享指针并将其复制ptr到其中.内部的引用计数shared_ptr确保内部分配的对象ptr被安全地转移到向量中.

没有解释的是析构函数shared_ptr<gate>确保删除分配的内存.这是避免内存泄漏的地方.析构函数用于std::vector<T>确保为T向量中存储的每个元素调用析构函数.但是,指针的析构函数(例如gate*)不会删除已分配的内存.这是你试图通过使用shared_ptr或避免的ptr_vector.

  • @Ahmed:整个表达式是一个变量初始化,就像你可能会编写`int x(5);`来初始化`x`一样,值为5.在这种情况下,它是用new-expression的值初始化的创造一个'ANDgate`; new-expression的值是指向新对象的指针. (6认同)

Ken*_*mon 40

我将增加约重要的事情是一个shared_ptr的是只有不断构建他们的语法如下:

shared_ptr<Type>(new Type(...));
Run Code Online (Sandbox Code Playgroud)

这样,"真实" Type指针对您的作用域是匿名的,并且由共享指针保持.因此,你不可能意外地使用这个"真正的"指针.换句话说,永远不要这样做:

Type* t_ptr = new Type(...);
shared_ptr<Type> t_sptr ptrT(t_ptr);
//t_ptr is still hanging around!  Don't use it!
Run Code Online (Sandbox Code Playgroud)

虽然这可以工作,但是现在你的函数中有一个Type*指针(t_ptr),它位于共享指针之外.在t_ptr任何地方使用都很危险,因为你永远不知道持有它的共享指针什么时候可能会破坏它,你就会发生段错误.

对于其他类返回给您的指针也是如此.如果你没有写一个班级给你一个指针,那么将它放入一个指针通常是不安全的shared_ptr.除非您确定该类不再使用该对象,否则不会.因为如果你把它放在a中shared_ptr,并且它超出了范围,当该类可能仍然需要它时,该对象将被释放.

  • 一切都肯说的是真与善,但我相信现在叫它的首选方法是`汽车t_ptr = make_shared <类型>(...);`或`等效的shared_ptr <类型> t_ptr = make_shared <类型>(.. .);`,只是因为那种形式更有效率. (6认同)

Jus*_*mer 19

学习使用智能指针是我认为成为一名称职的C++程序员最重要的步骤之一.如您所知,每当您在某个时刻新建一个对象时,您想要将其删除.

出现的一个问题是,除了异常之外,确保在所有可能的执行路径中始终只释放一次对象是非常困难的.

这就是RAII的原因:http://en.wikipedia.org/wiki/RAII

创建一个帮助类,目的是确保在所有执行路径中始终删除一个对象.

像这样的类的示例是:std :: auto_ptr

但有时你喜欢与其他人分享对象.它只应在不再使用时删除.

为了帮助完成该引用,已经开发了计数策略,但您仍需要手动记住addref和release ref.实质上,这与new/delete相同.

这就是为什么boost开发了boost :: shared_ptr,它是引用计数智能指针,因此你可以无意中共享对象而不是泄漏内存.

随着C++ tr1的加入,现在它也被添加到c ++标准中,但它的名字是std :: tr1 :: shared_ptr <>.

如果可能,我建议使用标准共享指针.ptr_list,ptr_dequeue等是指针类型的IIRC专用容器.我暂时忽略它们.

所以我们可以从你的例子开始:

std::vector<gate*> G; 
G.push_back(new ANDgate);  
G.push_back(new ORgate); 
for(unsigned i=0;i<G.size();++i) 
{ 
  G[i]->Run(); 
} 
Run Code Online (Sandbox Code Playgroud)

这里的问题是,每当G超出范围我们泄漏添加到G的2个对象.让我们重写它以使用std :: tr1 :: shared_ptr

// Remember to include <memory> for shared_ptr
// First do an alias for std::tr1::shared_ptr<gate> so we don't have to 
// type that in every place. Call it gate_ptr. This is what typedef does.
typedef std::tr1::shared_ptr<gate> gate_ptr;    
// gate_ptr is now our "smart" pointer. So let's make a vector out of it.
std::vector<gate_ptr> G; 
// these smart_ptrs can't be implicitly created from gate* we have to be explicit about it
// gate_ptr (new ANDgate), it's a good thing:
G.push_back(gate_ptr (new ANDgate));  
G.push_back(gate_ptr (new ORgate)); 
for(unsigned i=0;i<G.size();++i) 
{ 
   G[i]->Run(); 
} 
Run Code Online (Sandbox Code Playgroud)

当G超出范围时,内存会自动回收.

作为一个我困扰我团队中的新人的练习是要求他们编写自己的智能指针类.然后你完成后立即丢弃课程,再也不用了.希望您获得关于智能指针如何工作的关键知识.真的没有魔力.