📄 subject_48902.htm
字号:
<p>
序号:48902 发表者:耿文韬 发表日期:2003-08-04 21:28:11
<br>主题:关于dynamic_cast得问题!
<br>内容:class ZooAnimal { <BR>public:<BR> ZooAnimal():_loc(8),_name(""){<BR> cout<<"ZooAnimal::ZooAnimal()\n";<BR> } <BR> ZooAnimal(string &s,int loc):_name(s),_loc(loc){<BR> cout<<"ZooAnimal::ZooAnimal(string &s)\n";<BR> }<BR> virtual ~ZooAnimal(){<BR> cout<<"ZooAnimal::~ZooAnimal()\n";<BR> }<BR><BR> virtual void rotate(){<BR> cout<<"ZooAnimal::rotate()\n";<BR> } <BR>protected: <BR> int _loc; <BR> string _name; <BR>}; <BR><BR>class Panda:public ZooAnimal<BR>{<BR>public:<BR> Panda():_age(0){<BR> cout<<"Panda::Panda()\n";<BR> }<BR> Panda(int age):_age(age){<BR> cout<<"Panda::Panda(int)\n";<BR> }<BR> ~Panda(){<BR> cout<<"Panda::~Panda(int)\n";<BR> }<BR> void rotate(){<BR> cout<<"Panda::rotate()\n";<BR> } <BR> int GetAge(){<BR> return _age;<BR> }<BR>protected:<BR> int _age;<BR>};<BR><BR>void main()<BR>{<BR> ZooAnimal *pza2=new Panda(12);<BR> Panda* pp=dynamic_cast<Panda*>(pza2); //?<BR> cout<<pp->GetAge()<<endl; //?<BR> delete pza2;<BR>}<BR><BR>编译出警告:warning C4541: 'dynamic_cast' used on polymorphic type 'class ZooAnimal' with /GR-; unpredictable behavior may result<BR>如果把后面有//?得两句删掉,则程序编译通过,而且运行正常.<BR>加上去以后,竟然什么都不输出,就出现debug error警告,说abnormal program termination.<BR>我觉得好像没错啊,为什么不能运行,请大侠指教!!
<br><a href="javascript:history.go(-1)">返回上页</a><br><a href=http://www.copathway.com/cndevforum/>访问论坛</a></p>
<hr size=1>
<blockquote><p>
回复者:木一 回复日期:2003-08-04 21:51:00
<br>内容:基类的指针可以指向子类(倒过来不行),所以不用动态转换<BR><BR><BR><BR>这里会用到OOP编程中的多态性(滞后联编),把需要重载的函数用virtual修饰就可以了<BR><BR>另外<BR>基类并没有GetAge()啊?<BR><BR><BR>你的编程风络怪怪的哟?写什么程序呢?动物园里面的吗?好有趣哟。
<br>
<a href="javascript:history.go(-1)">返回上页</a><br><a href=http://www.copathway.com/cndevforum/>访问论坛</a></p></blockquote>
<hr size=1>
<blockquote><p>
回复者:耿文韬 回复日期:2003-08-04 22:04:02
<br>内容:我是把基类指针转成派生类 啊,然后调用派生类里的函数GetAge()啊
<br>
<a href="javascript:history.go(-1)">返回上页</a><br><a href=http://www.copathway.com/cndevforum/>访问论坛</a></p></blockquote>
<hr size=1>
<blockquote><p>
回复者:木一 回复日期:2003-08-04 22:21:13
<br>内容:你可以直接用基类的指针调用派生类的函数啊<BR><BR>class Base<BR>{<BR>public:<BR>virtual int GetAge() = 0;<BR>};<BR><BR>class Sub: public Base<BR>{<BR>virtual int GetAge() { return 100;}<BR>};<BR>使用的时候就可以<BR>Base *pBase = new Sub();<BR>pBase->GetAget();<BR><BR>delete pBase;<BR><BR> 这时,调用的实际上就是派生类的GetAge();<BR>这就是多态性的精妙之处。<BR>
<br>
<a href="javascript:history.go(-1)">返回上页</a><br><a href=http://www.copathway.com/cndevforum/>访问论坛</a></p></blockquote>
<hr size=1>
<blockquote><p>
回复者:木一 回复日期:2003-08-04 22:27:11
<br>内容: <BR>#include <stdio.h><BR>class Base<BR>{<BR>public:<BR> virtual int GetAge() <BR> {<BR> return 0;<BR> };<BR>};<BR>class Sub: public Base<BR>{<BR>public:<BR> virtual int GetAge()<BR> {<BR> return 100;<BR> }<BR>};<BR>int main(int argc, char* argv[])<BR>{<BR><BR> Base* pBase = new Sub();<BR> int age = pBase->GetAge ();<BR> printf("%d",age);<BR> delete pBase;<BR> return 0;<BR>}<BR><BR>===========<BR>打印出来的结果是 100还不是0<BR>这就是C++最迷人的特性之一。<BR>
<br>
<a href="javascript:history.go(-1)">返回上页</a><br><a href=http://www.copathway.com/cndevforum/>访问论坛</a></p></blockquote>
<hr size=1>
<blockquote><p>
回复者:木一 回复日期:2003-08-04 22:29:46
<br>内容:当然,如果把 基类的GetAge前面的virtual去掉的话,那么多态性就没有了。<BR>输出的结果就是 0了。<BR><BR>
<br>
<a href="javascript:history.go(-1)">返回上页</a><br><a href=http://www.copathway.com/cndevforum/>访问论坛</a></p></blockquote>
<hr size=1>
<blockquote><p>
回复者:耿文韬 回复日期:2003-08-04 22:41:59
<br>内容:就是要调用普通函数GetAge()
<br>
<a href="javascript:history.go(-1)">返回上页</a><br><a href=http://www.copathway.com/cndevforum/>访问论坛</a></p></blockquote>
<hr size=1>
<blockquote><p>
回复者:耿文韬 回复日期:2003-08-04 22:43:36
<br>内容:所以才要用强制转换啊,pza2实际指向派生类啊
<br>
<a href="javascript:history.go(-1)">返回上页</a><br><a href=http://www.copathway.com/cndevforum/>访问论坛</a></p></blockquote>
<hr size=1>
<blockquote><p>
<font color=red>答案被接受</font><br>回复者:木一 回复日期:2003-08-05 00:22:37
<br>内容:你遇到的这个问题也让我重温了一下dynamic_cast<BR><BR>不知道你用的是什么编译器?我用的是VC6<BR><BR><BR>#include "stdafx.h"<BR>#include <iostream.h><BR>#include <string><BR>using namespace std;<BR><BR><BR>class ZooAnimal { <BR>public:<BR> ZooAnimal():_loc(8),_name(""){<BR> cout<<"ZooAnimal::ZooAnimal()\n";<BR> } <BR> ZooAnimal(string &s,int loc):_name(s),_loc(loc){<BR> cout<<"ZooAnimal::ZooAnimal(string &s)\n";<BR> }<BR> virtual ~ZooAnimal(){<BR> cout<<"ZooAnimal::~ZooAnimal()\n";<BR> }<BR><BR> virtual void rotate(){<BR> cout<<"ZooAnimal::rotate()\n";<BR> } <BR> <BR>protected: <BR> int _loc; <BR> string _name; <BR>}; <BR><BR>class Panda:public ZooAnimal<BR>{<BR>public:<BR> Panda():_age(0){<BR> cout<<"Panda::Panda()\n";<BR> }<BR> Panda(int age):_age(age){<BR> cout<<"Panda::Panda(int)\n";<BR> }<BR> ~Panda(){<BR> cout<<"Panda::~Panda(int)\n";<BR> }<BR> void rotate(){<BR> cout<<"Panda::rotate()\n";<BR> } <BR> int GetAge(){<BR> return _age;<BR> }<BR>protected:<BR> int _age;<BR>};<BR><BR>void main()<BR>{<BR> ZooAnimal *pza2=new Panda(12);<BR> // Panda* pp=dynamic_cast<Panda*>(pza2); //?<BR> Panda* pp =(Panda*) pza2; //// 用这样的代码,在VC6下是可以运行的。上面一行是你原来的代码,编译的时候,给出C4541警告,意思是是多态性中,有不可预知的行为<BR> cout<<pp->GetAge()<<endl; //?<BR> delete pza2;<BR>}<BR><BR>============<BR>查看MSDN相关章节之后,得出了dynamic_cast的使用方法,我总结如下(一家之言,欢迎斧正)<BR><BR>1。 在程序设计中,尽量不要使用到dynamic_cast,类型转换与面向对象程序设计思想背道而驰。<BR><BR>2。 dynamic_cast 用法一:Upcast <BR>如下:<BR>class B { ... };<BR>class C : public B { ... };<BR>class D : public C { ... };<BR><BR>void f(D* pd)<BR>{<BR> C* pc = dynamic_cast<C*>(pd); // ok: C 是直接基类类 // pc points to C subobject of pd <BR><BR> B* pb = dynamic_cast<B*>(pd); // ok: B 间接基类<BR> // pb points to B subobject of pd <BR> ...<BR>}<BR><BR>An upcast is an implicit conversion. <BR>3。 可以用void*进行转换<BR> Void* 可以值向任何类型的内存块<BR>class A { ... };<BR><BR>class B { ... };<BR><BR>void f()<BR>{<BR> A* pa = new A;<BR> B* pb = new B;<BR> void* pv = dynamic_cast<void*>(pa);<BR> // pv now points to an object of type A<BR> ...<BR> pv = dynamic_cast<void*>(pb);<BR> // pv now points to an object of type B<BR>}<BR><BR><BR><BR><BR>4。 dynamic_cast 向下转换的时候<BR>class B { ... };<BR>class D : public B { ... };<BR><BR>void f()<BR>{<BR> B* pb = new D; // unclear but ok<BR> B* pb2 = new B;<BR><BR> D* pd = dynamic_cast<D*>(pb); // ok: pb actually points to a D<BR> ...<BR> D* pd2 = dynamic_cast<D*>(pb2); //error: pb2 points to a B, not a D<BR> // pd2 == NULL<BR> ...<BR>}<BR><BR>5。多重继承的时候,情况更为复杂<BR><BR>参见:http://msdn.microsoft.com/library/default.asp?url=/library/en-us/vccelng/htm/express_72.asp<BR><BR><BR><BR><BR>
<br>
<a href="javascript:history.go(-1)">返回上页</a><br><a href=http://www.copathway.com/cndevforum/>访问论坛</a></p></blockquote>
<hr size=1>
<blockquote><p>
回复者:耿文韬 回复日期:2003-08-05 10:11:16
<br>内容:Panda* pp=dynamic_cast<Panda*>(pza2); 和 D* pd = dynamic_cast<D*>(pb);两句不是一个意思吗?<BR>-------------------------------------------<BR>class ZooAnimal { //...};<BR>class Panda:public ZooAnimal { //...};<BR>ZooAnimal *pza2=new Panda(12);<BR>-------------------------------------------<BR>class B { //... };<BR>class D : public B { //... }; <BR>B* pb = new D;<BR>------------------------------------------- <BR>向下转换啊,pza2实际指向的是Panda对象啊,就像pb实际指向D一样,为什么我的不行啊?<BR>Panda* pp=dynamic_cast<Panda*>(pza2);改成Panda* pp=(Panda*)pza2;就可以运行啦?为什么?这两个转换之间有什么区别?
<br>
<a href="javascript:history.go(-1)">返回上页</a><br><a href=http://www.copathway.com/cndevforum/>访问论坛</a></p></blockquote>
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -