1.shared_ptr 和 scoped_ptr 的不同之处
1.1.shared_ptr 是允许转让的,而 scoped_ptr 是不允许权限转让的,转让的代码实现和定义在后面几段中有详细介绍,
不过简单的说就是 scoped_ptr 不支持同时创建两个指向相同类型的 scoped_ptr 指针让他们指向同一个对象实例
1.2.shared_ptr 可以作为标准容器的元素,而 scoped_ptr 是不可以的
1.3. shared_ptr 支持空指针的创建(常用于查找对象指针的时候,如果查找不到返回空指针的情况,因为在这种情况下不能够简单的返回 NULL ),而scoped_ptr 却不支持空指针
1.4. shared_ptr 支持引用计数,只有它支持引用计数,所谓的引用计数就是指:
创建一个对象 T , 然后创建多个指向该对象的 shared_ptr n1...nx ; 每个指针 n* 通过调用 n*.use_count () 方法的返回值(int)便可以获知,
当前除了自己以外是否还有其它的shared_ptr 指针指向该对象实例 T。返回值(int) 便可以称作是该对象 T 的引用计数。
只有当引用计数的数值为 0 的时候,调用 shared_ptr.reset() 方法才会将该对象 T 的空间进行释放,
否则仅仅是当前调用 reset() 方法的shared_ptr 指针所指向的引用计数数值 -1 ,并断开指针和对象之间的关联。
做实验的时候,很多代码都是在前面的基础之上进行修改的,多少有一些重复的地方
2. scoped_ptr 和 shared_ptr 的模板定义方法
2.1. boost::scoped_ptr
-
namespace boost {
-
-
template<typename T> class scoped_ptr : noncopyable {
-
public:
-
explicit scoped_ptr(T* p = 0);
-
~scoped_ptr();
-
-
void reset(T* p = 0);
-
-
T& operator*() const;
-
T* operator->() const;
-
T* get() const;
-
-
void swap(scoped_ptr& b);
-
};
-
-
template<typename T>
-
void swap(scoped_ptr<T> & a, scoped_ptr<T> & b);
-
}
2.2. boost::shared_ptr
-
template <typename T>
-
class shared_ptr
-
{
-
public :
-
typedef T element_type ;
-
-
shared_ptr () ;
-
template<typename Y >
-
explicit shared_ptr ( Y *p ) ;
-
-
template <typename Y , typename D>
-
shared_ptr ( Y*p , D d ) ;
-
-
~shared_ptr () ;
-
-
shared_ptr (shared_ptr const & r ) ;
-
-
template <typename Y>
-
explicit shared_ptr ( std::auto_ptr <Y> & r ) ;
-
-
shared_ptr & operator=(shared_ptr const &r ) ;
-
-
template <typename Y>
-
shared_ptr &operator= (shared_ptr<Y> const &r ) ;
-
-
template <typename Y>
-
shared_ptr &operator=(std::auto_ptr<Y> &r ) ;
-
-
void reset () ;
-
-
template <typename Y>
-
void reset ( Y* p ) ;
-
-
template <typename Y, typename D>
-
void reset ( Y*p , D d ) ;
-
-
T & operator*() const ;
-
T * operator->() const ;
-
T * get () const ;
-
-
-
bool unique () const ;
-
long use_count () const ;
-
-
operator unspecified-bool-type () const ;
-
void swap( shared_ptr & b ) ;
-
} ;
3. 代码实例转让的含义
4. boost 中的 explicit/noncopyable 来实现 scoped_ptr 的禁止转让功能 , scoped_ptr 通过swap 来实现一定程度的转让功能
-
#include <boost/shared_ptr.hpp>
-
#include <boost/scoped_ptr.hpp>
-
#include <cstdio>
-
#include <cstdlib>
-
#include <iostream>
-
-
/**
-
this file is used to justify the difference between boost::scoped_ptr and boost::shared_ptr
-
results:
-
1. shared_ptr can hands in its possion on an object , however the scoped_ptr doesn't
-
2. when you write something to let scoped_ptr hands in its possion on some object
-
spaces allocated to that object will be released immediately
-
but , unfortunately the output contents won't be shown on the screen cause the error message
-
-
by Aimer
-
*/
-
-
-
-
template <typename T>
-
class sharedPtr
-
{
-
public :
-
typedef boost::shared_ptr<T> type ;
-
} ;
-
-
template <typename T>
-
class scopedPtr
-
{
-
public :
-
typedef boost::scoped_ptr<T> type ;
-
} ;
-
-
class obj
-
{
-
public :
-
obj ( std::string& n )
-
{
-
name = n ;
-
std::cout << "you get a obj " << name << std::endl ;
-
}
-
-
void print ()
-
{
-
std::cout << "the programmer loves " <<name << std::endl ;
-
}
-
-
~obj ()
-
{
-
std::cout << "good bye " << name << std::endl;
-
}
-
-
private :
-
std::string name ;
-
} ;
-
-
-
int main ( void )
-
{
-
std::string name ("kylin_zhang") ;
-
-
// first we test whether shared_ptr can transfer the possion of a obj instance
-
sharedPtr<obj>::type p1 (new obj(name)) ;
-
sharedPtr<obj>::type p2 = p1 ;
-
-
p2->print () ;
-
-
-
// then we test whether the scoped_ptr can hand in its possion of a obj
-
std::string name_ ("singer aimer") ;
-
scopedPtr<obj>::type q1 (new obj(name_)) ;
-
-
-
/*
-
remove the notes , if you want to check the error message
-
*/
-
std::cout << std::endl ;
-
-
std::cout << "here we will transfer the posssion from q1 to q2" <<std::endl;
-
scopedPtr<obj>::type q2 ;
-
q1.swap (q2) ;
-
// after this q1's object is handed to q2 , so , q1->print() will prompt error message
-
-
-
q2->print () ;
-
-
-
// q1->print () ; this will cause error , cause the space could only be visited by q2 itself
-
-
std::cout << "end of file pointers release their objects' space" <<std::endl ;
-
-
return 0 ;
-
}
-
#include <cstdio>
-
#include <iostream>
-
#include <cstdlib>
-
-
/**
-
this test is used to testify how does explicit works on class ' s constructors
-
-
by Aimer 5/11/2015
-
**/
-
-
class obj1
-
{
-
public :
-
explicit obj1 ( const obj1 & o )
-
{
-
name = o.name ;
-
}
-
-
explicit obj1 ( std::string& n )
-
{
-
name = n ;
-
}
-
void print ()
-
{
-
std::cout << " my name is obj1's " << name << std::endl ;
-
}
-
public :
-
std::string name ;
-
-
} ;
-
-
class obj2
-
{
-
public :
-
obj2( const obj2 &o)
-
{
-
name = o.name+" copyed " ;
-
}
-
-
obj2( std::string & n )
-
{
-
name = n;
-
}
-
-
void print ()
-
{
-
std::cout << "my name is obj2's " << name << std::endl ;
-
}
-
-
private :
-
std::string name ;
-
-
} ;
-
-
-
int main ( )
-
{
-
std::string name ("kylin") ;
-
-
std::cout << "ok here we test the explicit obj1's string and non-explicit obj2's string constructor " << std::endl ;
-
-
-
/*
-
this will arise error , cause the explicit of string parameter constructor
-
obj1 obj1_1 = name ;
-
obj1_1.print() ;
-
*/
-
-
// this will be ok
-
obj2 obj2_1 = name ;
-
obj2_1.print () ;
-
-
std::cout << "---------------------------------------------------------------------------------------------"<<std::endl ;
-
std::cout << "ok here we test the explicit obj1's string and non-explicit obj2's object & constructors " << std::endl ;
-
-
/**
-
right ! , following codes will arise error again , because of the explicit again
-
-
obj1 obj1_2 = obj1_1 ;
-
obj1_2.print () ;
-
*/
-
-
-
obj2 obj2_2 = obj2_1 ;
-
obj2_2.print () ;
-
-
-
return 0 ;
-
-
}
-
#include <cstdio>
-
#include <iostream>
-
#include <cstdlib>
-
-
/**
-
this test is used to testify how does explicit works on class ' s constructors
-
-
by Aimer 5/11/2015
-
**/
-
-
class obj1
-
{
-
public :
-
explicit obj1 ( const obj1 & o )
-
{
-
name = o.name+" copyed " ;
-
}
-
-
explicit obj1 ( std::string& n )
-
{
-
name = n ;
-
}
-
void print ()
-
{
-
std::cout << " my name is obj1's " << name << std::endl ;
-
}
-
public :
-
std::string name ;
-
-
} ;
-
-
class obj2
-
{
-
public :
-
obj2( const obj2 &o)
-
{
-
name = o.name+" copyed " ;
-
}
-
-
obj2( std::string & n )
-
{
-
name = n;
-
}
-
-
void print ()
-
{
-
std::cout << "my name is obj2's " << name << std::endl ;
-
}
-
-
private :
-
std::string name ;
-
-
} ;
-
-
-
int main ( )
-
{
-
std::string name ("kylin") ;
-
-
std::cout << "ok here we test the explicit obj1's string and non-explicit obj2's string constructor " << std::endl ;
-
-
-
/*
-
this will arise error , cause the explicit of string parameter constructor
-
obj1 obj1_1 = name ;
-
obj1_1.print() ;
-
*/
-
-
// this will be ok
-
obj2 obj2_1 = name ;
-
obj2_1.print () ;
-
-
std::cout << "---------------------------------------------------------------------------------------------"<<std::endl ;
-
std::cout << "ok here we test the explicit obj1's string and non-explicit obj2's object & constructors " << std::endl ;
-
-
/**
-
right ! , following codes will arise error again , because of the explicit
-
-
obj1 obj1_2 = obj1_1 ;
-
obj1_2.print () ;
-
*/
-
obj1 obj(name) ; // here we creates an obj1 's instance in right rules
-
obj.print () ; // if this work , it means every goes well in obj
-
-
obj1 obj1_3 (obj) ; // this line goes all right , cause explicit could not detect this , you can use noncopyable from boost
-
// to ban this , may be that's why we will use boost::noncopyable
-
obj1_3.print () ;
-
-
obj2 obj2_2 = obj2_1 ;
-
obj2_2.print () ;
-
-
-
return 0 ;
-
-
}
5. shared_ptr和scoped_ptr 的声明与使用方法
6.关于 shared_ptr 中的引用计数的使用实例
-
#include <cstdio>
-
#include <iostream>
-
-
#include <boost/shared_ptr.hpp>
-
-
template <typename T>
-
class sharedPtr
-
{
-
public :
-
typedef boost::shared_ptr<T> type ;
-
} ;
-
-
typedef struct node
-
{
-
std::string name ;
-
node () : name(NULL)
-
{}
-
node ( std::string &n ) : name (n )
-
{}
-
-
~node ()
-
{
-
std::cout << "release node " << name << std::endl ;
-
}
-
-
void print ()
-
{
-
std::cout << "node name " << name << std::endl;
-
}
-
-
} node_t ;
-
-
-
template <typename T>
-
class shared_node
-
{
-
public :
-
shared_node ( typename sharedPtr<T>::type& n ) :node ( n )
-
{
-
// n->print () ;
-
-
}
-
/*
-
this constructor will not change the counter , because , it re-new an object
-
instead of create a pointer lets multi-pointers point to a same object's space
-
-
shared_node ( typename sharedPtr<T>::type n ) : node ( new T( *n) )
-
{
-
// node = typename sharedPtr<T>::type ( new T(*n) ) ; // counter == 1
-
}
-
*/
-
void print ()
-
{
-
std::cout<< "reference counter : " << node.use_count() << std::endl ;
-
node->print () ;
-
}
-
private :
-
typename sharedPtr<T>::type node ;
-
} ;
-
-
-
template <typename T>
-
void print_func ( typename sharedPtr<T>::type n)
-
{
-
std::cout << "reference counter :" << n.use_count() << std::endl ;
-
n->print () ;
-
}
-
-
int main ()
-
{
-
std::string name ("kylin_zhang") ;
-
-
std::cout << "================= print_func shows=======================" <<std::endl ;
-
-
sharedPtr<node_t>::type p ( new node_t (name) ) ; // use counter = 1
-
-
print_func<node_t>(p) ; // use counter = 2 , after get out of method , counter = 1
-
-
std::cout << "================= shared_node print shows=======================" <<std::endl ;
-
-
// sharedPtr<shared_node<node_t> >::type s1(p) , s2(p) ;
-
-
shared_node<node_t> s1(p) , s2(p) ;
-
-
std::cout << "p 's use counter " << p.use_count () << std::endl; // p's counter = 3
-
-
s1.print () ; // counter =1
-
-
s2.print () ; // s2's p's counter =1
-
-
-
while ( p.use_count() != 0 )
-
{
-
std::cout << "use counter " << p.use_count() << std::endl ;
-
p.reset() ;
-
-
// theory until p's use_counter == 0 , will p call delete method to release the space , if use_counter != 0 only executing use_counter-- operation
-
// but , in practice , p.reset() once , p.use_count() == 0 , what this hell ? i do not clear
-
}
-
std::cout << "================= destructor shows=======================" <<std::endl ;
-
return 0 ;
-
}
end
on line codes reference :
转让
转让 adds swap
adds explicity but without noncopyable
adds other detail
usage of scoped_ptr and shared_ptr
final usage of scoped_ptr and shared_ptr :
something about reference counter of shared_ptr
阅读(3933) | 评论(0) | 转发(0) |