先说点题外话。
在C++中,有两个行为:
- 如果某函数接受的参数不是期待的类型,编译器会尝试进行隐式的转换。将传入参数进行适配,使得函数调用能够成功
- 这样的隐式的转换只能进行一次。编译器不可能先将TypeA隐式转换为TypeB,接着又把TypeB隐式转换为TypeC
下面一段代码验证了这两个行为:
1 struct A
2 {
3 int _m;
4 A():_m(0){};
5 };
6
7 struct B
8 {
9 A _m;
10 int _alias;
11 B(A a):_m(a),_alias(0){};
12 };
13
14 struct C
15 {
16 B _m;
17 C(B b):_m(b){};
18 };
19
20 struct D
21 {
22 C _m;
23 D(C c):_m(c){};
24 };
25
26 A a;
27 B b(a);
28 C c1(b), c2(a), c3 = C(a);
29 // C c4 = a;
30 // D d1(a);
31 D d2(b);
对象a、b和c1创建时没有隐式转换。
对象c2和c3创建时,编译器将参数a隐式转换为一个临时的TypeB对象;d2创建时,编译器将参数b隐式转换为一二临时的TypeC对象。
对象c4不能被创建,因为编译器并不负责两次隐式转换(TypeA–>TypeB–>TypeC);同样d1也不能创建同样是因为需要两次隐式转换(TypeA->TypeB->TypeC)。
另外,copying函数指的是拷贝构造函数和赋值函数。
今天看《C++标准程序库:自修教程与参考手册》中关于auto_ptr的部分,提到它的copying函数只能用auto_ptr作参数,不能用普通指针。请看一下代码所表现的:
1 #include <memory>
2 using namespace std;
3
4 class A
5 {
6 };
7
8 auto_ptr<A> pa(new A);
9 auto_ptr<A> pb = pa;
10 auto_ptr<A> pc = auto_ptr<A>(new A);
11 // auto_ptr<A> pd = new A;
pb和pc可以被auto_ptr正确赋值,而pd不能被普通指针A*赋值。
这里涉及到的问题有两个:
- 为何要规定这种行为
- 内部是如何去实现的
第一个问题比较明了,因为auto_ptr中有“资源所有权”的问题,每时每刻,某一个资源(比如一块内存神马的)只能属于一个auto_ptr,因此在它的copying函数实现中,必定会包含有资源所有权转移的代码。而普通指针并没有所有权的概念,当然不能被作为copying函数的参数。这种行为肯定是应该禁止的。
而要回答第二个问题,请先看看本文开头描述的两种行为中的第一种,按说,在auto_ptr_copying中的pd被赋值时,new A应该可以由编译器隐式转换为anto_ptr类型的,怎么就失败了呢! 打开auto_ptr定义所在stl中的memory文件,源码是这样的:
1 template<typename _Tp>
2 class auto_ptr
3 {
4 private:
5 _Tp* _M_ptr;
6
7 public:
8 /// The pointed-to type.
9 typedef _Tp element_type;
10
11 /**
12 * @brief An %auto_ptr is usually constructed from a raw pointer.
13 * @param p A pointer (defaults to NULL).
14 *
15 * This object now @e owns the object pointed to by @a p.
16 */
17 explicit
18 auto_ptr(element_type* __p = 0) throw() : _M_ptr(__p) { }
19
20 // other source code
21 // ......
22 }
注意第17行上的修饰构造函数的explicit关键字,它规定auto_ptr的构造函数不能参与隐式转换(在隐式转换时禁止调用),只能显式进行转换,因此在auto_ptr_copying中没有隐式转换。问题貌似到此已经清楚了。
那么,如果不计后果地把这个explicit给去掉呢?是不是就可以进行隐式转换了?结果是否定的。
auto_ptr的copying函数大有玄机,回头看看本文开头描述的两种行为中的第二种,再结合这篇专门讲述auto_ptr_ref的文章,应该就豁然开朗了!
原文链接: https://www.cnblogs.com/springlie/archive/2012/11/14/auto_ptr-copying-member-func.html
欢迎关注
微信关注下方公众号,第一时间获取干货硬货;公众号内回复【pdf】免费获取数百本计算机经典书籍
原创文章受到原创版权保护。转载请注明出处:https://www.ccppcoding.com/archives/69438
非原创文章文中已经注明原地址,如有侵权,联系删除
关注公众号【高性能架构探索】,第一时间获取最新文章
转载文章受原作者版权保护。转载请注明原作者出处!