auto_ptr实现之我见

        笔者在网上看到很少有解答这个问题的文章,有的写得很晦涩,所以把自己的一些体会拿出来与大家分享,以求共同的进步!

        C++标准中,rvalue(右值)是不能改变的,lvalue是可以改变的。(注1:rvalue和lvalue来源于赋值表达式,后来rvalue引申为那些不能改变的变量,lvalue引申为可以改变的变量。)
        C++标准认为临时变量不应该被修改,所以临时变量是一种rvalue,当一条语句执行后,其中的临时变量即被释放,之后当然无从修改。只有一种情况,临时变量不被释放,那就是const&它。
        在C++中,对一个rvalue(如临时变量)只能常引用(reference to const),不能一般引用,如:
        int const& i = 60;
        int const& rf = fun();//fun()是右值,fun()返回一个int临时变量是合法的。
        在向函数传递参数时,也有类似的情况,如果参数是引用一个临时变量,那么必须是const&(一般情况,临时变量)。
        一般的构造函数和operator=函数是const&变量的,因为它们通常允许用临时变量作为参数,如:std::pair<int, int>(3, 4)。auto_ptr的copy构造函数和operator=函数也应该具备这样的能力,但是如果真的const&另一个auto_ptr临时变量,那么同时又要拿取该变量的ownership(它的指针),这显然是对其的修改,与C++标准精神不符。如果普通引用一个auto_ptr临时变量,这与C++标准精神简直就是矛盾(右值只能const&)。
        不能将一个类的对象作为传值参数给copy构造函数,因为传值参数实际上调用copy构造函数,这样会递归调用,因此,copy构造函数的参数必须是该类对象的引用,同时为了能接受临时变量,参数还必须是常量引用(const reference),即const&。
        以上就是全部问题,如果你没有答案的话,不必过于放在心上,当时C++标准委员会很多人都束手无策,法国代表团甚至主张丢弃auto_ptr,对亏了Greg和Bill提出了'auto_ptr_ref'的想法,这才使我们能使用这个C++中目前唯一的Smart Pointer,实现方法如下:

/* special conversions with auxiliary type to enable copies and assignments */
//这三个函数都是在auto_ptr中声明的
//注意这不是copy构造函数,而是一个转换构造函数
auto_ptr(auto_ptr_ref<T> rhs) throw()
: ap(rhs.yp) {
}
//注意这也不是一般的赋值运算符函数,一般的赋值运算符函数的参数是const&
auto_ptr& operator= (auto_ptr_ref<T> rhs) throw() { //new
reset(r.yp);
return *this;
}
//这是转换运算符函数,它使auto_ptr可以显式/隐式地转换成一个auto_ptr_ref
template<class Y>
operator auto_ptr_ref<Y>() throw() {
return auto_ptr_ref<Y>(release());
}
        这三个函数解决了上述问题,即我们现在可以用一个auto_ptr给另一个auto_ptr赋值和初始化,同时其ownership被release()。
        其中转换运算符函数和转换构造函数是关键,它们提供了显式/隐式地在auto_ptr与auto_ptr_ref之间的转换。隐式转换至多一次。如果你不了解这两种函数,可以找一本较详细的C++书看看。看似copy构造函数的手法,但根本与copy构造函数无关,这就是该方法的妙处。
        从而,auto_ptr<int> a(auto_ptr<int>(new int(0)))的真正执行如下:
1 准备调用auto_ptr(auto_ptr_ref<T> rhs),但发现参数不是auto_ptr_ref<T>,同时发现转换运算符函数auto_ptr_ref<Y>(),便隐式调用之得到auto_ptr_ref<int>的临时变量,并使auto_ptr_ref<int>临时变量release()失去ownership。
2 用auto_ptr(auto_ptr_ref<T> rhs)构造a。

        赋值过程与此相似,请自行解释。

(未经本人同意请勿转载)

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值