個人檔案Quake3 启示录相片部落格清單更多 工具 說明

部落格


3月4日

smart_ptr 使用例子

使用智能指针不会因为忘记delete指针而造成内存泄露。还有当第三方的lib中某些函数返回指针,这样的返回的指针被client使用的时候,lib就会失去对返回的指针的控制,这样delete的指针的任务一般就会交给调用方client,但是如果client忘记调用delete或是调用的时机不正确,都有可能导致问题,在这种情况下最好使用智能指针。
使用智能指针的典型情况:
使用智能指针可以保证异常安全
保证程序在有异常抛出时仍然无内存泄露。
智能指针更好的解决了资源的所有权共享               

shared_ptr<boost/shared_ptr.hpp>:使用shared_ptr进行对象的生存期自动管理,使得分享资源所有权变得有效且安全.      scoped_ptr<boost/scoped_ptr.hpp>: 用于确保能够正确地删除动态分配的对象。scoped_ptr 有着与std::auto_ptr类似的特性,而最大的区别在于它不能转让所有权而auto_ptr可以。事实上,scoped_ptr永远不能被复制或被赋值!scoped_ptr 拥有它所指向的资源的所有权,并永远不会放弃这个所有权。 
weak_ptr<boost/weak_ptr.hpp>:weak_ptr 是 shared_ptr 的观察员。它不会干扰shared_ptr所共享的所有权。当一个被weak_ptr所观察的 shared_ptr 要释放它的资源时,它会把相关的 weak_ptr的指针设为空。使用此辅助指针一般是防止悬空指针。intrusive_ptr<boost/intrusive_ptr.hpp>:shared_ptr的插入是版本,一般不使用,因为需要对使用此指针的类型中增加ref计数功能。但是可以保证不增加指针的大小。
scoped_array<boost/scoped_array.hpp>: scoped_array 为数组做了scoped_ptr为单个对象的指针所做的事情:它负责释放内存。
shared_array<boost/shared_array.hpp>: shared_array 用于共享数组所有权的智能指针。一般指向std::vector的shared_ptr提供了比shared_array更多的灵活性,所以一般使用std::vector<shared_ptr>。


环境boost1_38_0
#include <iostream>
#include <string>
#include <vector>
#include <boost/smart_ptr.hpp>
#include <boost/any.hpp>
#include <boost/format.hpp>

void PrintIfString(const boost::any& Any)
{
    const boost::shared_ptr<std::string> *s =
        boost::any_cast<boost::shared_ptr<std::string> >(&Any);
    if (s && *s)
    {
        std::cout << **s << std::endl;        
    }

    const boost::weak_ptr<std::string>* s1 =
        boost::any_cast< boost::weak_ptr<std::string> >(&Any);
    if(s1)
    {       
        const boost::shared_ptr<std::string> s = s1->lock();
        if(s)
        {
            std::cout<<"weak: "<< *s <<std::endl;
        }
    }

}

int main(int argc, char* argv[])
{
    std::vector<boost::any> Stuff;
    boost::shared_ptr<std::string> SharedString1(new std::string(
        "Share me.By the way,Boost.any is another useful Boost library"));
    boost::shared_ptr<std::string> SharedString2(SharedString1);
    boost::shared_ptr<int> SharedInt1(new int(42));
    boost::shared_ptr<int> SharedInt2 (SharedInt1);
    boost::weak_ptr<std::string> ShareString3(SharedString2);
    //SharedString1.reset(); 重置智能指针为NULL
    //SharedString2.reset();
    Stuff.push_back(SharedString1);
    Stuff.push_back(SharedString2);
    Stuff.push_back(SharedInt1);
    Stuff.push_back(SharedInt2);   
    Stuff.push_back(ShareString3);
    for_each(Stuff.begin(), Stuff.end(), PrintIfString);
    Stuff.clear();

    return 0;
}

scoped_prt 源码中,支持 if(smartptr) 判断的实现
typedef T * this_type::*unspecified_bool_type;
operator unspecified_bool_type() const
{
    return px == 0? 0: &this_type::px;
}

令人发晕的类型unspecified_bool_type,这种类型实际上是"指向类的某内部成员变量的指针",不要认为它是指针类型(c必知必会上有说明)。(可以参考<<深入c++对象模型>>来查看这样的偏移值是多少)。unspecified_bool_type可以被当作bool类型使用,它要么为0,要么为1(&this_type::px总是1,错误这个是类内部成员变量的偏移值,cout输出为1是因为转换为bool类型了,可以用printf(”%p”,xx)来打印值。注意vc做了特殊处理,第一个元素偏移值打印为0,不像深入c++对象模型说的是1. 但实际上是转换判断还是为 true 的。

注意这样使用:    boost::shared_ptr<int> SharedInt1(new int(42));  而不是先new 然后赋值智能指针。在函数参数上new可以保证异常安全。除了weak_ptr都可以按这种方法来使用。

在C++标准4.12节中, 对指针与布尔值之间的关系有大致如下的描述:
任何一个指针或成员对象指针都可以转换成布尔值,空指针转换成false, 其它值转换成true.
这样我们就可以利用成员指针来进行转换。通常成员指针不可能(至少不那种容易)被隐式转换(转换的前提毕竟是类型要匹配,或可向上转换)。

回應

請稍候...
很抱歉,您輸入的回應過長。請縮短您的回應。
您尚未輸入內容,請再試一次。
很抱歉,目前無法新增您的回應,請稍後再試。
若要新增回應,您的父母必須先給您權限。要求權限
您的家長已關閉回應功能。
很抱歉,目前無法刪除您的回應,請稍後再試。
您已超過每日回應上限次數,請於 24 小時後再試一次。
由於系統顯示您可能傳送垃圾郵件給其他使用者,因此您帳號中的回應功能已遭停用。 如果您認為自己帳號遭錯誤停用,請連絡 Windows Live 支援
請完成下列安全檢查,以完成回應。
您輸入的安全檢查字元必須與圖片或音訊中的字元相符。

若要新增回應,請以您的 Windows Live ID 登入 (若您使用 Hotmail、Messenger 或 Xbox LIVE,則您已擁有 Windows Live ID)。登入


沒有 Windows Live ID?註冊

引用通告

此內容的引用通告是:
http://topameng.spaces.live.com/blog/cns!F962D4854A8233D!533.trak
引述這則內容的部落格