码迷,mamicode.com
首页 > 编程语言 > 详细

C++ auto_ptr

时间:2018-03-26 00:52:30      阅读:166      评论:0      收藏:0      [点我收藏+]

标签:namespace   隐式转换   所有权   实现   other   之一   思想   body   传递   

虽然auto_ptr已经过时了, 但是对这种古董做考古工作仍旧有很多裨益。

#include <iostream>
#include <memory>
using namespace std;

struct S{
    ~S(){
        std::cout << "~S() called" << std::endl;
    }
};

void foo( std::auto_ptr<S> ptr){
    //ptr.release();
}

int main () {
    std::auto_ptr<S> ptr(new S);
    foo(ptr);
    if (!ptr.get()){
        std::cout << "ptr is null" ;
    }
} 

所有权移交(总是move),是auto_ptr的核心语义之一。当调用foo(ptr)后,会打印输出“ptr is null” 。

为了防止发生foo中的行为,可以定成:

1 void foo( const std::auto_ptr<S>& other){
2      //other.release(); //compile error。 const& ptr 阻止了对ptr.release(). 
3 }

那么auto_ptr中的拷贝构造函数是什么样子的?

auto_ptr( const auto_ptr& other);     //这绝不可能,为了实现唯一所有权,我们需要对other.release(); 显然const阻止了这个事情的发生。

auto_ptr( auto_ptr& other);   //正确的。

那么这又怎么解释?

std::auto_ptr<S> makeS(){
    std::auto_ptr<S> ret();    
    return ret;
}

std::auto_ptr<S> a = makeS();

C++03时代,makeS()返回右值,右值只能传递给auto_ptr(const auto_ptr& other);或者 auto_ptr( auto_ptr&& other); 可惜这两个函数都不存在。

解决办法就是:auto_ptr_ref. 本质是个抓右值的工具(在C++03时代,是个开创性的发明)。右值std::auto_ptr<S>隐式转换成auto_ptr_ref<S>, 传递给template< class Y > auto_ptr( auto_ptr_ref<Y> m );

下面是模拟,先提出一个问题,是C++03无法编译的:

#include <iostream>
using namespace std;

struct S{
   
    S(int i){
        std::cout << "S(int i) called \n";
        i_in_s_ = i;
    }
    
    S(S &s){
        std::cout << "S(S s) called \n";
    }

    int i_in_s_;
};

int main(){
    S b = S(1);
}

还是那个T& 无法绑定右值的问题,解决如下:

#include <iostream>using namespace std;

struct S{
    
    struct S_ref{
        S_ref(int i): i_(i){ }
        int i_;
    };
    
    operator S_ref(){
        std::cout << "operator S_ref called \n";
        return S_ref(i_in_s_);
    }
    
    S(int i){
        std::cout << "S(int i) called \n";
        i_in_s_ = i;
    }
    
    S(S &s){
        std::cout << "S(S s) called \n";
    }
    
    S(S_ref r){
        std::cout << "S(S_ref r) called \n";
        i_in_s_ = r.i_;
        
    }
    int i_in_s_;
};

int main(){
    S b = S(1);
}

解决。思想就是:抓右值的目的,无非就是想拷贝点东西出来吧。我先把东西拷贝到S_ref,然后再传给S(S_ref r)。也能实现传递数据的功能。

考古工作暂时告一段落。

C++ auto_ptr

标签:namespace   隐式转换   所有权   实现   other   之一   思想   body   传递   

原文地址:https://www.cnblogs.com/thomas76/p/8647694.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!