3.2.4 与auto_ptr的区别
scoped_ptr的用法与auto_ptr几乎一样,大多数情况下它可以与auto_ptr相互替换,它也可以从一个auto_ptr获得指针的管理权(同时auto_ptr失去管理权)。
scoped_ptr也具有auto_ptr同样的"缺陷"--不能用作容器的元素,但原因不同:auto_ptr是因为它的转移语义,而scoped_ptr则是因为不支持拷贝和赋值,不符合容器对元素类型的要求。
scoped_ptr与auto_ptr的根本性区别在于指针的所有权。auto_ptr特意被设计为指针的所有权是可转移的,可以在函数之间传递,同一时刻只能有一个auto_ptr管理指针。它的用意是好的,但转移语义太过于微妙,不熟悉auto_ptr特性的初学者很容易误用引发错误。而scoped_ptr把拷贝构造函数和赋值函数都声明为私有的,拒绝了指针所有权的转让--除了scoped_ptr自己,其他任何人都无权访问被管理的指针,从而保证了指针的绝对安全。
下面的代码清楚地演示了两者的区别:
- auto_ptr<int> ap(new int(10)); //一个int自动指针
- scoped_ptr<int> sp(ap); //从auto_ptr获得原始指针
- assert(ap.get() == 0); //原auto_ptr不再拥有指针
-
- ap.reset(new int(20)); //auto_ptr拥有新的指针
- cout << *ap << "," << *sp << endl;
-
- auto_ptr<int> ap2;
- apap2 = ap; //ap2从ap获
得原始指针,发生所有权转移 - assert(ap.get() == 0); //ap不再拥有指针
- scoped_ptr<int> sp2; //另一个scoped_ptr
- spsp2 = sp; //赋值操作,
无法通过编译!!
如果代码编写者企图从一个scoped_ptr构造或赋值另一个scoped_ptr(代码的最后一行),那么编译器会报出一个错误,阻止他这么做,从而保护了你的代码,而且是在编译期。
比起auto_ptr,scoped_ptr更明确地表明了代码原始编写者的意图:只能在定义的作用域内使用,不可转让,这在代码后续的维护生命周期中很重要。