Dad*_*dyM 0 c++ casting auto-ptr
请帮我理解以下问题.
看下面的代码示例:
#include <iostream>
class Shape {
public:
virtual wchar_t *GetName() { return L"Shape"; }
};
class Circle: public Shape {
public:
wchar_t *GetName() { return L"Circle"; }
double GetRadius() { return 100.; }
};
int wmain() {
using namespace std;
auto_ptr<Shape> aS;
auto_ptr<Circle> aC(new Circle);
aS = aC;
wcout << aS->GetName() << L'\t' << static_cast<auto_ptr<Circle>>(aS)->GetRadius() << endl;
return 0;
}
Run Code Online (Sandbox Code Playgroud)
为什么我不被允许这样做:
static_cast<auto_ptr<Circle>>(aS)->GetRadius()
Run Code Online (Sandbox Code Playgroud)
编译器(MSVCPP 11):
1>c:\program files (x86)\microsoft visual studio 11.0\vc\include\xmemory(911): error C2440: 'initializing' : cannot convert from 'Shape *' to 'Circle *'
1> Cast from base to derived requires dynamic_cast or static_cast
Run Code Online (Sandbox Code Playgroud)
auto_ptr
在这方面的行为与指针的行为不同.语言中有一些特殊规则允许在派生时Shape*
使用static_cast .向下转换并不完全是类型安全的,因为它依赖于用户提供实际指向a的基类子对象的指针值,但标准允许它为方便起见.是"只是"一个库类,并没有等效的转换.Circle*
Circle
Shape
Shape
Circle
auto_ptr
即使你能做到,也常常会出错.复制时auto_ptr
,原始设备将失去对资源的所有权.您static_cast
将复制auto_ptr
到临时,因此aS
将被重置,并且当临时(在表达式结束时)资源将被销毁.在你的例子中没问题,因为它return
无论如何都会被破坏,但一般来说你不想复制auto_ptr
除了函数调用参数或返回值,以指示从调用者到被调用者的所有权转移,反之亦然.
您可以做的是static_cast<Circle*>(aS.get())->GetRadius()
,或者更好地重构代码以避免需要向下转换.如果您知道对象是a Circle
,请将其保存在auto_ptr<Circle>
[*]中.如果你保持它auto_ptr<Shape>
,那么不要依赖它Circle
.
[*]或者,如果您的实现提供了它们,可以使用更好的智能指针,例如unique_ptr
,scoped_ptr
或shared_ptr
.即使你的实现没有提供它们,也有Boost.
归档时间: |
|
查看次数: |
3314 次 |
最近记录: |