dynamic_cast,我需要更多的解释.

元明 2000-03-30 01:55:00
加精
dynamic_cast是c++ builder的专有操作符吗,另我还想对这个操作符进行更深的理解,越详细越好.
...全文
412 6 打赏 收藏 转发到动态 举报
写回复
用AI写文章
6 条回复
切换为时间正序
请发表友善的回复…
发表回复
ploto 2000-04-12
  • 打赏
  • 举报
回复
dynamic_cast<T*>(source)
是在运行时检查source,如果source是与T相容的类型,则将返回一个T类型的指针,否则返回一个NULL值。
例:
class A{...};
class B:publicA {...};
void foo(A* a1)
{
B* b1=dynamic_cast<A*>(a1); //1:
}
上述语句1:如果没有dynamic_cast,在编译时是错误的,因为a1指向一个A类型的指针,B是A的子类,父类的指针是不能直接转换成子类的指针的。但是加上dynamic_cast之后,该语句就是合法的,如果a1确实是一个指向B类或B的子类的指针,那么b1就会指向一个正确的值。否则b1为NULL。在C++BUILDER中举一个简单的例子
在FORM1上放一个BUTTON控件。在Button控件的Click事件中加入以下的代码,再让FORM共享该事件句柄,观察一下实际响应情况。
void __fastcall TForm1::Button1Click(TObject* Sender)
{
TButton* pBtn=dynamic_cast<TButton*>(Sender);
if(pBtn)
{
pBtn->Caption="您在BUTTON是按下鼠标了";
}
else
{
ShowMessage("您没有在BUTTON上按下鼠标");
}

}
再简单描述一下static_cast操作符:
static_cast操作符是在编译时决定指针的类型。以下两句语句是等价并且是合法的
class A{...};
class B:public A{...};
void foo(B* b1)
{
A* a1=(A*)b1;
A* a1=static_cast<A*>(b1);
}
如果要深入研究下的的话,就会发现a1指针并不一定与b1指针相等。编译器在将b1转换成a1时会作一定的运算。不过作为程序员,我们可以不考虑这些。

另外一个运算符是 reinterpret_cast操作符,上一次我把这个词拼错了:-{ , reinterpret_cast操作符可以转换两个不相关的类型,例:
class A{...};
class B{...};
void foo(void* v)
{
B* b;
A* a1=reinterpret_cast<A*>v; //合法的,如果v是一个A类型,那么它就是正确的。
A* a1=reinterpret_cast<A*>b; //合法的,但是是错误的。
}
如果是子类向父类转换,可以用静态指针(static_cast及其等价的强制类型转换),只有当将传递的父类指针参数转换成子类时,才需要用dynamic_cast
另外还有一个操作符叫const_cast 该运算符我到现在还没有用过,可查找一下MSDN上的说明。
ploto 2000-04-07
  • 打赏
  • 举报
回复
在C++中,强制类型转换有几种:直接类型转换、static_cast、dyanmic_cast和reinterrupt_cast。分述如下:
直接类型转换:该转换只能用于相容的类型转换,只能将子类转换成父类
dynamic_cast:类似于DELPHI中的AS运算符这是一个RTTI类型运算符。运算符的格式象这样dynamic_cast<type*>(source)可将source转换成为一个type类型的指针。如果source是一个与type相容的类型,则返回该类型,可以使用该类型中的所有的公共函数。如果source类型与type类型不相容(既不是type类型,又不是type类型的子类)则该运算符将返回一个空值。
reinterrupt_cast可将所有的类型进行转换,例如将一个VOID类型转换成一个类。象这种强制转换最主要的用处是在消息处理过程中。通过这种方式,可以将一个类型的实例的地址放到消息的WParam或LParam中进行传送。

元明 2000-04-05
  • 打赏
  • 举报
回复
wingsun,halfdream能说得更详细一点吗?
halfdream 2000-04-02
  • 打赏
  • 举报
回复
我看有资料上说它是BCB特别的运算符,
反正就是强类型转换的,
如果转换不成功就返回NUL值(可能就是这个地方同标准的方法有点区别)。
Wingsun 2000-04-01
  • 打赏
  • 举报
回复
用法如下:
void __fastcall TFrmBuilding::EdtBPhotoExit(TObject *Sender)
{
if(!isNumberic(dynamic_cast<TEdit*>(Sender)->Text))
{
dynamic_cast<TEdit*>(Sender)->Text="0";
}
}
使用dynamic_cast<Class *> (Source *)将Source类型的指针转换为Class类型的。但是Class 与Source 的关系为父类与子类的关系。
元明 2000-04-01
  • 打赏
  • 举报
回复
是不是大家都不懂,怎末没人来.
以下是关于dynamic_cast的文档,中文是我翻译的(我的E文不好),还有例程,可我看了还是不清楚,切盼高手.


In the expression, dynamic_cast< T > (ptr), T must be a pointer or a reference to a defined class type or void*. The argument ptr must be an expression that resolves to a pointer or reference.
在这个表达式中,dynamic_cast< T > (ptr), T 必须是一个指针或一个引用类或Void指针,ptr变量必须是一个表达式才能够分解前面的指针或定义的类.


If T is void* then ptr must also be a pointer. In this case, the resulting pointer can access any element of the class that is the most derived element in the hierarchy. Such a class cannot be a base for any other class.
如果T是Void指针则ptr必须同样是一个指针.在这个格式里,作为结果的指针才能够访问在这个层次上的派生类中的元素.这一个类不能是任何其它类的基类.



Conversions from a derived class to a base class, or from one derived class to another, are as follows: if T is a pointer and ptr is a pointer to a non-base class that is an element of a class hierarchy, the result is a pointer to the unique subclass. References are treated similarly. If T is a reference and ptr is a reference to a non-base class, the result is a reference to the unique subclass.
从一个派生类转化为一个基类或其它的类,则有以下规定:假入T是一个指针,ptr指向一个不是基类的此层上的类元素.则结果指向一个唯一的子类.引用也一样,如果T是一个引用且Ptr是一派生类引用,则结果是子类引用.



A conversion from a base class to a derived class can be performed only if the base is a polymorphic type.
从基类转化为派生类(基类是多态性).



The conversion to a base class is resolved at compile time. A conversion from a base class to a derived class, or a conversion across a hierarchy is resolved at runtime.




If successful, dynamic_cast< T > (ptr) converts ptr to the desired type. If a pointer cast fails, the returned pointer is valued 0. If a cast to a reference type fails, the Bad_cast exception is thrown.

Note: Runtime type identification (RTTI) is required for dynamic_cast.




// HOW TO MAKE DYNAMIC CASTS

// This program must be compiled with the -RT (Generate RTTI) option.
#include <iostream.h>
#include <typeinfo.h>

class Base1
{
// In order for the RTTI mechanism to function correctly,
// a base class must be polymorphic.
virtual void f(void) { /* A virtual function makes the class polymorphic */ }
};

class Base2 { };
class Derived : public Base1, public Base2 { };

int main(void) {
try {
Derived d, *pd;
Base1 *b1 = &d;

// Perform a downcast from a Base1 to a Derived.

if ((pd = dynamic_cast<Derived *>(b1)) != 0) {
cout << "The resulting pointer is of type "
<< typeid(pd).name() << endl;
}
else throw Bad_cast();

// Attempt cast across the hierarchy. That is, cast from
// the first base to the most derived class and then back
// to another accessible base.
Base2 *b2;
if ((b2 = dynamic_cast<Base2 *>(b1)) != 0) {
cout << "The resulting pointer is of type "

<< typeid(b2).name() << endl;
}
else throw Bad_cast();
}
catch (Bad_cast) {
cout << "dynamic_cast failed" << endl;
return 1;
}
catch (...) {
cout << "Exception handling error." << endl;
return 1;
}

return 0;

}

13,822

社区成员

发帖
与我相关
我的任务
社区描述
C++ Builder相关内容讨论区
社区管理员
  • 基础类社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧