我有我的基类,如下所示:
class point //concrete class
{
... //implementation
}
class subpoint : public point //concrete class
{
... //implementation
}
如何从一个点对象转换为下点对象? 我已经尝试了所有三个如下:
point a;
subpoint* b = dynamic_cast<subpoint*>(&a);
subpoint* b = (subpoint*)a;
subpoint b = (subpoint)a;
什么是错的,这些类型转换?
如何从一个点对象转换为下点对象?
你不能; 除非任何point
具有转换操作,或subpoint
具有转换构造,在这种情况下的对象类型可以与不需要的铸造进行转换。
你可以从铸point
引用 (或指针)到subpoint
引用 (或指针),如果称为对象是类型的实际上subpoint
:
subpoint s;
point & a = s;
subpoint & b1 = static_cast<subpoint&>(a);
subpoint & b2 = dynamic_cast<subpoint&>(a);
第一( static_cast
)更危险的; 没有检查,转换是有效的,因此,如果a
不指subpoint
,然后用b1
将有不确定的行为。
第二( dynamic_cast
)是安全的,但如果只会工作point
是多态的(也就是说,如果它有一个虚函数)。 如果a
指的是不兼容的类型的对象,那么它会抛出异常。
对于第一个例子, dynamic_cast
如果有在基类的至少一个虚拟方法仅适用。 如果对象实际上不是你想投的类型,它会导致NULL。
对于第二个例子,你需要&a
而不是a
,但一旦你定,你会得到不确定的行为,因为对象类型是错误的。
第三个例子需要一个operator subpoint()
在方法point
做了转化率,同时创建一个副本。
动态铸件的目的在于“在运行时检查对象是否是特定类型的层次结构中的的”。 所以,现在让我们来看看你有什么:
- 你有一个点对象。 没有一个下点。
- 你问一个动态转换,如果对象是下点。 不是。
- 因为它不是一个下点时,将dynamic_cast失败 - 它告诉你,对象不是你想将它转换为类型的方式。
与此相反,这会工作:
subpoint c;
point *a = &c;
subpoint* b = dynamic_cast<subpoint*>(&a);
subpoint* b = (subpoint*)a;
总体来说,这是行不通的,因为point
是不是一个subpoint
; 只有正好相反。 不过,也有其他一些问题。
为了:
subpoint* b = dynamic_cast<subpoint*>(&a);
dynamic_cast
仅适用于多态类型,即至少声明一个虚函数的类型。 我的猜测是, point
没有虚函数,这意味着它不能被使用dynamic_cast
。
subpoint* b = (subpoint*)a;
对于这个投地工作, point
需要声明一个转换操作符来subpoint *
,如point::operator subpoint *()
subpoint b = (subpoint)a;
对于这个投地工作,一点需要声明一个转换操作符来subpoint
或 subpoint
需要有一个构造函数参数从可转换point
。
什么是错的,这些类型转换?
你试图做他们的事实。 一个point
是不是subpoint
,我会感到惊讶,如果它的工作。
a
不能被制作成subpoint
。 该实现是不存在的。