⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 subject_48902.htm

📁 一些关于vc的问答
💻 HTM
字号:
<p>
序号:48902 发表者:耿文韬 发表日期:2003-08-04 21:28:11
<br>主题:关于dynamic_cast得问题!
<br>内容:class ZooAnimal { <BR>public:<BR>&nbsp;&nbsp;&nbsp;&nbsp;ZooAnimal():_loc(8),_name(""){<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;cout&lt;&lt;"ZooAnimal::ZooAnimal()\n";<BR>&nbsp;&nbsp;&nbsp;&nbsp;} <BR>&nbsp;&nbsp;&nbsp;&nbsp;ZooAnimal(string &amp;s,int loc):_name(s),_loc(loc){<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; cout&lt;&lt;"ZooAnimal::ZooAnimal(string &amp;s)\n";<BR>&nbsp;&nbsp;&nbsp;&nbsp;}<BR>&nbsp;&nbsp;&nbsp;&nbsp;virtual ~ZooAnimal(){<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;cout&lt;&lt;"ZooAnimal::~ZooAnimal()\n";<BR>&nbsp;&nbsp;&nbsp;&nbsp;}<BR><BR>&nbsp;&nbsp;&nbsp;&nbsp;virtual void rotate(){<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;cout&lt;&lt;"ZooAnimal::rotate()\n";<BR>&nbsp;&nbsp;&nbsp;&nbsp;} <BR>protected: <BR>&nbsp;&nbsp;&nbsp;&nbsp;int _loc; <BR>&nbsp;&nbsp;&nbsp;&nbsp;string _name; <BR>}; <BR><BR>class Panda:public ZooAnimal<BR>{<BR>public:<BR>&nbsp;&nbsp;&nbsp;&nbsp;Panda():_age(0){<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;cout&lt;&lt;"Panda::Panda()\n";<BR>&nbsp;&nbsp;&nbsp;&nbsp;}<BR>&nbsp;&nbsp;&nbsp;&nbsp;Panda(int age):_age(age){<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;cout&lt;&lt;"Panda::Panda(int)\n";<BR>&nbsp;&nbsp;&nbsp;&nbsp;}<BR>&nbsp;&nbsp;&nbsp;&nbsp;~Panda(){<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;cout&lt;&lt;"Panda::~Panda(int)\n";<BR>&nbsp;&nbsp;&nbsp;&nbsp;}<BR>&nbsp;&nbsp;&nbsp;&nbsp;void rotate(){<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;cout&lt;&lt;"Panda::rotate()\n";<BR>&nbsp;&nbsp;&nbsp;&nbsp;} <BR>&nbsp;&nbsp;&nbsp;&nbsp;int GetAge(){<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;return _age;<BR>&nbsp;&nbsp;&nbsp;&nbsp;}<BR>protected:<BR>&nbsp;&nbsp;&nbsp;&nbsp;int _age;<BR>};<BR><BR>void main()<BR>{<BR>&nbsp;&nbsp;&nbsp;&nbsp;ZooAnimal *pza2=new Panda(12);<BR>&nbsp;&nbsp;&nbsp;&nbsp;Panda* pp=dynamic_cast&lt;Panda*&gt;(pza2);&nbsp;&nbsp;//?<BR>&nbsp;&nbsp;&nbsp;&nbsp;cout&lt;&lt;pp-&gt;GetAge()&lt;&lt;endl;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;//?<BR>&nbsp;&nbsp;&nbsp;&nbsp;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-&gt;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 &lt;stdio.h&gt;<BR>class Base<BR>{<BR>public:<BR>&nbsp;&nbsp;&nbsp;&nbsp;virtual int GetAge() <BR>&nbsp;&nbsp;&nbsp;&nbsp;{<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;return 0;<BR>&nbsp;&nbsp;&nbsp;&nbsp;};<BR>};<BR>class Sub: public Base<BR>{<BR>public:<BR>&nbsp;&nbsp;&nbsp;&nbsp;virtual int GetAge()<BR>&nbsp;&nbsp;&nbsp;&nbsp;{<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;return 100;<BR>&nbsp;&nbsp;&nbsp;&nbsp;}<BR>};<BR>int main(int argc, char* argv[])<BR>{<BR><BR>&nbsp;&nbsp;&nbsp;&nbsp;Base* pBase = new Sub();<BR>&nbsp;&nbsp;&nbsp;&nbsp;int age = pBase-&gt;GetAge ();<BR>&nbsp;&nbsp;&nbsp;&nbsp;printf("%d",age);<BR>&nbsp;&nbsp;&nbsp;&nbsp;delete pBase;<BR>&nbsp;&nbsp;&nbsp;&nbsp;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 &lt;iostream.h&gt;<BR>#include &lt;string&gt;<BR>using namespace std;<BR><BR><BR>class ZooAnimal { <BR>public:<BR>&nbsp;&nbsp;&nbsp;&nbsp;ZooAnimal():_loc(8),_name(""){<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;cout&lt;&lt;"ZooAnimal::ZooAnimal()\n";<BR>&nbsp;&nbsp;&nbsp;&nbsp;} <BR>&nbsp;&nbsp;&nbsp;&nbsp;ZooAnimal(string &amp;s,int loc):_name(s),_loc(loc){<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; cout&lt;&lt;"ZooAnimal::ZooAnimal(string &amp;s)\n";<BR>&nbsp;&nbsp;&nbsp;&nbsp;}<BR>&nbsp;&nbsp;&nbsp;&nbsp;virtual ~ZooAnimal(){<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;cout&lt;&lt;"ZooAnimal::~ZooAnimal()\n";<BR>&nbsp;&nbsp;&nbsp;&nbsp;}<BR><BR>&nbsp;&nbsp;&nbsp;&nbsp;virtual void rotate(){<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;cout&lt;&lt;"ZooAnimal::rotate()\n";<BR>&nbsp;&nbsp;&nbsp;&nbsp;} <BR> <BR>protected: <BR>&nbsp;&nbsp;&nbsp;&nbsp;int _loc; <BR>&nbsp;&nbsp;&nbsp;&nbsp;string _name; <BR>}; <BR><BR>class Panda:public ZooAnimal<BR>{<BR>public:<BR>&nbsp;&nbsp;&nbsp;&nbsp;Panda():_age(0){<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;cout&lt;&lt;"Panda::Panda()\n";<BR>&nbsp;&nbsp;&nbsp;&nbsp;}<BR>&nbsp;&nbsp;&nbsp;&nbsp;Panda(int age):_age(age){<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;cout&lt;&lt;"Panda::Panda(int)\n";<BR>&nbsp;&nbsp;&nbsp;&nbsp;}<BR>&nbsp;&nbsp;&nbsp;&nbsp;~Panda(){<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;cout&lt;&lt;"Panda::~Panda(int)\n";<BR>&nbsp;&nbsp;&nbsp;&nbsp;}<BR>&nbsp;&nbsp;&nbsp;&nbsp;void rotate(){<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;cout&lt;&lt;"Panda::rotate()\n";<BR>&nbsp;&nbsp;&nbsp;&nbsp;} <BR>&nbsp;&nbsp;&nbsp;&nbsp;int GetAge(){<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;return _age;<BR>&nbsp;&nbsp;&nbsp;&nbsp;}<BR>protected:<BR>&nbsp;&nbsp;&nbsp;&nbsp;int _age;<BR>};<BR><BR>void main()<BR>{<BR>&nbsp;&nbsp;&nbsp;&nbsp;ZooAnimal *pza2=new Panda(12);<BR> //&nbsp;&nbsp;Panda* pp=dynamic_cast&lt;Panda*&gt;(pza2);&nbsp;&nbsp;//?<BR>&nbsp;&nbsp;&nbsp;&nbsp;Panda* pp =(Panda*) pza2; //// 用这样的代码,在VC6下是可以运行的。上面一行是你原来的代码,编译的时候,给出C4541警告,意思是是多态性中,有不可预知的行为<BR>&nbsp;&nbsp;&nbsp;&nbsp;cout&lt;&lt;pp-&gt;GetAge()&lt;&lt;endl;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;//?<BR>&nbsp;&nbsp;&nbsp;&nbsp;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>&nbsp;&nbsp; C* pc = dynamic_cast&lt;C*&gt;(pd);&nbsp;&nbsp; // ok: C 是直接基类类&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; // pc points to C subobject of pd <BR><BR>&nbsp;&nbsp; B* pb = dynamic_cast&lt;B*&gt;(pd);&nbsp;&nbsp; // ok: B 间接基类<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; // pb points to B subobject of pd <BR>&nbsp;&nbsp; ...<BR>}<BR><BR>An upcast is an implicit conversion. <BR>3。 可以用void*进行转换<BR>&nbsp;&nbsp;&nbsp;&nbsp;Void* 可以值向任何类型的内存块<BR>class A { ... };<BR><BR>class B { ... };<BR><BR>void f()<BR>{<BR>&nbsp;&nbsp; A* pa = new A;<BR>&nbsp;&nbsp; B* pb = new B;<BR>&nbsp;&nbsp; void* pv = dynamic_cast&lt;void*&gt;(pa);<BR>&nbsp;&nbsp; // pv now points to an object of type A<BR>&nbsp;&nbsp; ...<BR>&nbsp;&nbsp; pv = dynamic_cast&lt;void*&gt;(pb);<BR>&nbsp;&nbsp; // pv now points to an object of type B<BR>}<BR><BR><BR><BR><BR>4。 dynamic_cast&nbsp;&nbsp;向下转换的时候<BR>class B { ... };<BR>class D : public B { ... };<BR><BR>void f()<BR>{<BR>&nbsp;&nbsp; B* pb = new D;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; // unclear but ok<BR>&nbsp;&nbsp; B* pb2 = new B;<BR><BR>&nbsp;&nbsp; D* pd = dynamic_cast&lt;D*&gt;(pb);&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;// ok: pb actually points to a D<BR>&nbsp;&nbsp; ...<BR>&nbsp;&nbsp; D* pd2 = dynamic_cast&lt;D*&gt;(pb2);&nbsp;&nbsp; //error: pb2 points to a B, not a D<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;// pd2 == NULL<BR>&nbsp;&nbsp; ...<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&lt;Panda*&gt;(pza2); 和&nbsp;&nbsp;D* pd = dynamic_cast&lt;D*&gt;(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 { //... };&nbsp;&nbsp;<BR>B* pb = new D;<BR>------------------------------------------- <BR>向下转换啊,pza2实际指向的是Panda对象啊,就像pb实际指向D一样,为什么我的不行啊?<BR>Panda* pp=dynamic_cast&lt;Panda*&gt;(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 + -