// testSmartPtr.cpp : Defines the entry point for the console application.
//
#include "stdafx.h"
#include
#include
#include
#include
#include
/*
Title:智能指针使用示例
Author:kagula
date:2010-02-02
LastUpdate:2016-12-19
Enviroment:
[1]Visual Studio 2008 + SP1
Visual Studio 2013 Udpate5
[2]Boost 1.48
*/
class MyClass{
public:
MyClass(std::string my_name)
{
this->my_name = my_name;
std::cout << "我[" << my_name.c_str() << "]被实例化了!" << std::endl;
};
void DoSomething()
{
std::cout << "我[" << my_name.c_str() << "]干了些什么!" << std::endl;
}
void DoSomething(std::string sT)
{
std::cout << "[" << my_name.c_str() << "]" << sT << std::endl;
}
~MyClass()
{
std::cout << "我[" << my_name.c_str() << "]要被释放了!" << std::endl;
}
private:
std::string my_name;
};
class DerivedFromMyClass : public MyClass{
public:
DerivedFromMyClass(std::string myName) :MyClass(myName)
{
}
void DoSomething2(std::string sT)
{
std::cout << sT << std::endl;
}
};
class ESFT :public boost::enable_shared_from_this
{
public:
void DoSomething()
{
boost::shared_ptr pESFT = shared_from_this();
}
};
int _tmain(int argc, _TCHAR* argv[])
{
{
/*
auto_ptr
[1]不能作为container 的元素。
[2]采用了所有权转移的机制,不符合STL container 元素的要求。
[3]不能用于动态创建的数组。
头文件定义:#include
*/
//分配
std::auto_ptr pMyObject(new MyClass("auto_ptr test!"));
//控制权转移,原指针无效
std::auto_ptr pNow = pMyObject;
//调用实例方法
pNow->DoSomething();
pNow.get()->DoSomething();//不建议这样使用
//打印指针地址
std::cout << "指针所指向的实例地址:" << pNow.get() << std::endl;
}
std::cout << "--------------------------------------------------------------------" << std::endl;
{
/*
boost::scoped_ptr
[1]boost::scoped_ptr和std::auto_ptr的功能和操作都非常类似,如何在他们之间选取
取决于是否需要转移所管理的对象的所有权(如是否需要作为函数的返回值)
头文件定义:#include
参考资料:《Boost智能指针——scoped_ptr》
http://www.cnblogs.com/TianFang/archive/2008/09/15/1291050.html
*/
//分配
boost::scoped_ptr pMyObject(new MyClass("scoped_ptr test!"));
//调用实例方法
pMyObject->DoSomething();
}
std::cout << "--------------------------------------------------------------------" << std::endl;
{
/*
boost::shared_ptr
[1]boost::shared_ptr采用引用计数,计数器到零时释放对象
[2]注意:循环引用问题
[3]推荐在涉及到STL的场合中使用,免得带来CopyConstruct性能损失
[4]下行不能用dynamic_pointer_cast来转,原因不明
[5]static_pointer_cast同dynamic_pointer_cast,有什么区别?
头文件定义:#include
参考资料:《使用Boost智能指针》
http://blog.chinaunix.net/u2/62093/showart_484486.html
*/
//分配
boost::shared_ptr pMyObject(new MyClass("shared_ptr test!"));
boost::shared_ptr pMyObject2 = pMyObject;
//通过裸指针直接使用实例的方法
{
boost::shared_ptr pMyObject3 = boost::make_shared(MyClass("shared_ptr test 2016-12-19!"));
MyClass* pMC = pMyObject3.get();
pMC->DoSomething();
//退出block后,会看到释放被析构两次,但是只分配了一次,程序还是正常运行,不知道什么原因。
}
//调用实例方法
pMyObject->DoSomething();
pMyObject2->DoSomething();
std::cout << "----上行引用示例----" << std::endl;
//上行引用示例
boost::shared_ptr pDMC(new DerivedFromMyClass("上行引用示例"));
pDMC->DoSomething("pDMC->DoSomething");
pDMC->DoSomething2("pDMC->DoSomething2");
boost::shared_ptr pMC(pDMC);
boost::shared_ptr pMC2 = boost::static_pointer_cast(pDMC);
boost::shared_ptr pMC3 = boost::dynamic_pointer_cast(pDMC);
pMC->DoSomething("pMC->DoSomething");
pMC2->DoSomething("pMC2->DoSomething");
pMC3->DoSomething("pMC3->DoSomething");
assert(pMC2 == pMC3); //static_pointer_cast同dynamic_pointer_cast是一样的,不知道什么区别。
std::cout << "----下行引用示例----" << std::endl;
//下行引用示例一
boost::shared_ptr pDMC2 = boost::static_pointer_cast(pMC);
pDMC2->DoSomething2("pDMC2->DoSomething2");
//下行引用示例二
boost::shared_ptr pMC4(new MyClass("下行引用示例二 "));
//猜测下面这段话,MyClass实例变成了DerivedFromMyClass实例
boost::shared_ptr pDMC3 = boost::static_pointer_cast(pMC4);
pDMC3->DoSomething();
pDMC3->DoSomething2("abcdef");//所以这句statement才不会报错
}
std::cout << "--------------------------------------------------------------------" << std::endl;
{
/*
boost::weak_ptr
[1]boost::weak_ptr的主要目的是为了解决两对象间的计数的循环引用问题
[2]weak_ptr 是 shared_ptr 的观察员。它不会干扰shared_ptr所共享的所有权。
当一个被weak_ptr所观察的 shared_ptr 要释放它的资源时,它会把相关的 weak_ptr的指针设为空。
使用此辅助指针一般是防止悬空指针。
头文件定义:#include
参考资料:《weak_ptr class template》
http://www.boost.org/doc/libs/1_41_0/libs/smart_ptr/weak_ptr.htm
*/
//分配
boost::shared_ptr pMyObject(new MyClass("shared_ptr,weak_ptr test!"));
boost::weak_ptr pWeak(pMyObject);
// 如果所指向的实例存在,返回boost::shared_ptr对象,否则返回NULL
if (boost::shared_ptr r = pWeak.lock())
{
r->DoSomething();
}
}
std::cout << "--------------------------------------------------------------------" << std::endl;
{
/*
下列关键词
enable_shared_from_this
shared_from_this
使用目的:
获取弱指针(shared_from_this)
使用需要注意以下几点
[1] 不要在构造函数中使用shared_from_this;
[2] 其次,如果要使用shared_ptr,则应该在所有地方均使用,
[3] 不能使用D d这种方式,也决不要传递裸指针。
[4] 另一个值得注意的地方是在类的继承树中不能有2个或更多个enable_shared_from_this
头文件定义:#include
参考资料:《shared_from_this 几个值得注意的地方》
http://bbs.rosoo.net/viewthread.php?tid=90
*/
std::cout << "enable_shared_from_this test .begin" << std::endl;
boost::shared_ptr pESFT(new ESFT());
std::cout << "enable_shared_from_this test .end" << std::endl;
}
std::cout << "--------------------------------------------------------------------" << std::endl;
{
/*
Intrusive_ptr——轻量级共享智能指针
说明:
唯一需要插入式智能指针的情况是,被指类的某个成员函数需要返回this,
以便它可以用于另一个智能指针(事实上,也有办法使用非插入式智能指针来解决这个问题,正如我们在本章前面看到的)。
intrusive_ptr 不同于其它智能指针,因为它要求你来提供它所要的引用计数器。
头文件定义:#include
备注:因为很少用到不做该类型指针测试了,具体如何实现Intrusive_ptr可以查看《参考资料》
参考资料:《使用Boost智能指针》
http://blog.chinaunix.net/u2/62093/showart_484486.html
《intrusive_ptr用法》
http://hi.baidu.com/_%E2d_%B7%B3_%C2%D2/blog/item/85e38d884b264f90a4c272a0.html
*/
}
return 0;
}