C++ auto_ptr

虽然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)。也能实现传递数据的功能。

考古工作暂时告一段落。

原文链接: https://www.cnblogs.com/thomas76/p/8647694.html

欢迎关注

微信关注下方公众号,第一时间获取干货硬货;公众号内回复【pdf】免费获取数百本计算机经典书籍;

也有高质量的技术群,里面有嵌入式、搜广推等BAT大佬

    C++ auto_ptr

原创文章受到原创版权保护。转载请注明出处:https://www.ccppcoding.com/archives/397530

非原创文章文中已经注明原地址,如有侵权,联系删除

关注公众号【高性能架构探索】,第一时间获取最新文章

转载文章受原作者版权保护。转载请注明原作者出处!

(0)
上一篇 2023年4月11日 上午9:14
下一篇 2023年4月11日 上午9:14

相关推荐