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

📄 subject_44117.htm

📁 一些关于vc的问答
💻 HTM
字号:
<p>
序号:44117 发表者:老狼寺主持 发表日期:2003-06-16 19:24:42
<br>主题:虚函数
<br>内容:我在学习C++的时候,虚函数是个难题,请教各位大虾虚函数应该怎么学啊?多谢啊!!!!!!
<br><a href="javascript:history.go(-1)">返回上页</a><br><a href=http://www.copathway.com/cndevforum/>访问论坛</a></p>
<hr size=1>
<blockquote><p>
回复者:擎天柱 回复日期:2003-06-16 19:32:37
<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-06-16 19:46:45
<br>内容:反复学,就会渐进的明白了<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-06-16 22:23:21
<br>内容:多谢啊!!!不过我还是不太明白。davidbao能不能详细的讲下,<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>
回复者:duanruiyu 回复日期:2003-06-17 08:40:30
<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>
<font color=red>答案被接受</font><br>回复者:bird 回复日期:2003-06-17 09:11:17
<br>内容:虚函数是动态联编的基础。虚函数是成员函数,而且是非static的成员函数。说明虚函数的方法如下:<BR><BR> <BR><BR>&nbsp;&nbsp;&nbsp;&nbsp;virtual &lt;类型说明符&gt;&lt;函数名&gt;(&lt;参数表&gt;)<BR><BR> <BR><BR>&nbsp;&nbsp;&nbsp;&nbsp;其中,被关键字virtual说明的函数称为虚函数。<BR><BR> <BR><BR>&nbsp;&nbsp;&nbsp;&nbsp;如果某类中的一个成员函数被说明为虚函数,这就意味着该成员函数在派生类中可能有不同的实现。当使用这个成员函数操作指针或引用所标识对象时,对该成员函数调用采取动态联编方式,即在运行时进行关联或束定。<BR><BR> <BR><BR>&nbsp;&nbsp;&nbsp;&nbsp;动态联编只能通过指针或引用标识对象来操作虚函数。如果采用一般类型的标识对象来操作虚函数,则将采用静态联编方式调用虚函数。<BR><BR> <BR><BR>&nbsp;&nbsp;&nbsp;&nbsp;下面给出一个动态联编的例子:<BR><BR> <BR><BR>&nbsp;&nbsp;&nbsp;&nbsp;#include &lt;iostream.h&gt;<BR><BR> <BR><BR>&nbsp;&nbsp;&nbsp;&nbsp;class Point<BR><BR>&nbsp;&nbsp;&nbsp;&nbsp;{<BR><BR>&nbsp;&nbsp;&nbsp;&nbsp;public:<BR><BR>&nbsp;&nbsp;&nbsp;&nbsp;Point(double i, double j) { x=i; y=j; }<BR><BR>&nbsp;&nbsp;&nbsp;&nbsp;virtual double Area() const { return 0.0; }<BR><BR>&nbsp;&nbsp;&nbsp;&nbsp;private:<BR><BR>&nbsp;&nbsp;&nbsp;&nbsp;double x, y;<BR><BR>&nbsp;&nbsp;&nbsp;&nbsp;};<BR><BR>&nbsp;&nbsp;&nbsp;&nbsp;class Rectangle:public Point<BR><BR>&nbsp;&nbsp;&nbsp;&nbsp;{<BR><BR>&nbsp;&nbsp;&nbsp;&nbsp;public:<BR><BR>&nbsp;&nbsp;&nbsp;&nbsp;Rectangle(double i, double j, double k, double l);<BR><BR>&nbsp;&nbsp;&nbsp;&nbsp;//double Area() const { return w*h; }<BR><BR>&nbsp;&nbsp;&nbsp;&nbsp;virtual double Area() const { return w*h; }<BR><BR>&nbsp;&nbsp;&nbsp;&nbsp;private:<BR><BR>&nbsp;&nbsp;&nbsp;&nbsp;double w, h;<BR><BR>&nbsp;&nbsp;&nbsp;&nbsp;};<BR><BR>&nbsp;&nbsp;&nbsp;&nbsp;Rectangle::Rectangle(double i, double j, double k, double l):Point(i, j)<BR><BR>&nbsp;&nbsp;&nbsp;&nbsp;{<BR><BR>&nbsp;&nbsp;&nbsp;&nbsp;w=k; h=l;<BR><BR>&nbsp;&nbsp;&nbsp;&nbsp;}<BR><BR>&nbsp;&nbsp;&nbsp;&nbsp;void fun(Point &amp;s)<BR><BR>&nbsp;&nbsp;&nbsp;&nbsp;{<BR><BR>&nbsp;&nbsp;&nbsp;&nbsp;cout&lt;&lt;s.Area()&lt;&lt;endl;<BR><BR>&nbsp;&nbsp;&nbsp;&nbsp;}<BR><BR> <BR><BR>&nbsp;&nbsp;&nbsp;&nbsp;void main()<BR><BR>&nbsp;&nbsp;&nbsp;&nbsp;{<BR><BR>&nbsp;&nbsp;&nbsp;&nbsp;Rectangle rec(3.0, 5.2, 15.0, 25.0);<BR><BR>&nbsp;&nbsp;&nbsp;&nbsp;fun(rec);<BR><BR>&nbsp;&nbsp;&nbsp;&nbsp;}<BR><BR> <BR><BR>&nbsp;&nbsp;&nbsp;&nbsp;通过这个例子可以看到,派生类中对基类的虚函数进行替换时,要求派生类中说明的虚函数与基类中的被替换的虚函数之间满足如下条件:<BR><BR> <BR><BR>&nbsp;&nbsp;&nbsp;&nbsp;(1) 与基类的虚函数有相同的参数个数;<BR><BR>&nbsp;&nbsp;&nbsp;&nbsp;(2) 其参数的类型与基类的虚函数的对应参数类型相同;<BR><BR>&nbsp;&nbsp;&nbsp;&nbsp;(3) 其返回值或者与基类虚函数的相同,或者都返回指针或引用,并且派生类虚函数所返回的指针或引用的基类型是基类中被替换的虚函数所返回的指针或引用的基类型的子类型。<BR><BR> <BR><BR>&nbsp;&nbsp;&nbsp;&nbsp;满足上述条件的派生类的成员函数,自然是虚函数,可以不必加virtaul说明。<BR><BR> <BR><BR>&nbsp;&nbsp;&nbsp;&nbsp;总结动态联编的实现需要如下三个条件:<BR><BR> <BR><BR>&nbsp;&nbsp;&nbsp;&nbsp;(1) 要有说明的虚函数;<BR><BR>&nbsp;&nbsp;&nbsp;&nbsp;(2) 调用虚函数操作的是指向对象的指针或者对象引用;或者是由成员函数调用虚函数;<BR><BR>&nbsp;&nbsp;&nbsp;&nbsp;(3) 子类型关系的建立。<BR><BR> <BR><BR>&nbsp;&nbsp;&nbsp;&nbsp;以上结果可用以下例子证实。<BR><BR> <BR><BR>&nbsp;&nbsp;&nbsp;&nbsp;#include &lt;iostream.h&gt;<BR><BR> <BR><BR>&nbsp;&nbsp;&nbsp;&nbsp;class A<BR><BR>&nbsp;&nbsp;&nbsp;&nbsp;{<BR><BR>&nbsp;&nbsp;&nbsp;&nbsp;public:<BR><BR>&nbsp;&nbsp;&nbsp;&nbsp;virtual void act1();<BR><BR>&nbsp;&nbsp;&nbsp;&nbsp;void act2()<BR><BR>&nbsp;&nbsp;&nbsp;&nbsp;{<BR><BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;act1();<BR><BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;this-&gt;act1();<BR><BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;A::act1();<BR><BR>&nbsp;&nbsp;&nbsp;&nbsp;}<BR><BR>&nbsp;&nbsp;&nbsp;&nbsp;};<BR><BR> <BR><BR>&nbsp;&nbsp;&nbsp;&nbsp;void A::act1()<BR><BR>&nbsp;&nbsp;&nbsp;&nbsp;{<BR><BR>&nbsp;&nbsp;&nbsp;&nbsp;cout&lt;&lt;"A::act1() called."&lt;&lt;endl;<BR><BR>&nbsp;&nbsp;&nbsp;&nbsp;}<BR><BR> <BR><BR>&nbsp;&nbsp;&nbsp;&nbsp;class B : public A<BR><BR>&nbsp;&nbsp;&nbsp;&nbsp;{<BR><BR>&nbsp;&nbsp;&nbsp;&nbsp;public:<BR><BR>&nbsp;&nbsp;&nbsp;&nbsp;void act1();<BR><BR>&nbsp;&nbsp;&nbsp;&nbsp;};<BR><BR> <BR><BR>&nbsp;&nbsp;&nbsp;&nbsp;void B::act1()<BR><BR>&nbsp;&nbsp;&nbsp;&nbsp;{<BR><BR>&nbsp;&nbsp;&nbsp;&nbsp;cout&lt;&lt;"B::act1() called."&lt;&lt;endl;<BR><BR>&nbsp;&nbsp;&nbsp;&nbsp;}<BR><BR> <BR><BR>&nbsp;&nbsp;&nbsp;&nbsp;void main()<BR><BR>&nbsp;&nbsp;&nbsp;&nbsp;{<BR><BR>&nbsp;&nbsp;&nbsp;&nbsp;B b;<BR><BR>&nbsp;&nbsp;&nbsp;&nbsp;b.act2();<BR><BR>&nbsp;&nbsp;&nbsp;&nbsp;}<BR><BR> <BR><BR>&nbsp;&nbsp;&nbsp;&nbsp;构造函数中调用虚函数时,采用静态联编即构造函数调用的虚函数是自己类中实现的虚函数,如果自己类中没有实现这个虚函数,则调用基类中的虚函数,而不是任何涶生类中实现的虚函数。<BR><BR> <BR><BR>&nbsp;&nbsp;&nbsp;&nbsp;下面通过一个例子说明在构造函数中如何调用虚函数。<BR><BR> <BR><BR>&nbsp;&nbsp;&nbsp;&nbsp;#include &lt;iostream.h&gt;<BR><BR> <BR><BR>&nbsp;&nbsp;&nbsp;&nbsp;class A<BR><BR>&nbsp;&nbsp;&nbsp;&nbsp;{<BR><BR>&nbsp;&nbsp;&nbsp;&nbsp;public:<BR><BR>&nbsp;&nbsp;&nbsp;&nbsp;A() {}<BR><BR>&nbsp;&nbsp;&nbsp;&nbsp;virtual void f() { cout&lt;&lt;"A::f() called.\n"; }<BR><BR>&nbsp;&nbsp;&nbsp;&nbsp;};<BR><BR> <BR><BR>&nbsp;&nbsp;&nbsp;&nbsp;class B : public A<BR><BR>&nbsp;&nbsp;&nbsp;&nbsp;{<BR><BR>&nbsp;&nbsp;&nbsp;&nbsp;public:<BR><BR>&nbsp;&nbsp;&nbsp;&nbsp;B() { f(); }<BR><BR>&nbsp;&nbsp;&nbsp;&nbsp;void g() { f(); }<BR><BR>&nbsp;&nbsp;&nbsp;&nbsp;};<BR><BR> <BR><BR>&nbsp;&nbsp;&nbsp;&nbsp;class C : public B<BR><BR>&nbsp;&nbsp;&nbsp;&nbsp;{<BR><BR>&nbsp;&nbsp;&nbsp;&nbsp;public:<BR><BR>&nbsp;&nbsp;&nbsp;&nbsp;C() {}<BR><BR>&nbsp;&nbsp;&nbsp;&nbsp;virtual void f() { cout&lt;&lt;"C::f() called.\n"; }<BR><BR>&nbsp;&nbsp;&nbsp;&nbsp;};<BR><BR> <BR><BR>&nbsp;&nbsp;&nbsp;&nbsp;void main()<BR><BR>&nbsp;&nbsp;&nbsp;&nbsp;{<BR><BR>&nbsp;&nbsp;&nbsp;&nbsp;C c;<BR><BR>&nbsp;&nbsp;&nbsp;&nbsp;c.g();<BR><BR>&nbsp;&nbsp;&nbsp;&nbsp;}<BR><BR> <BR><BR>&nbsp;&nbsp;&nbsp;&nbsp;上面程序的输出结果为:<BR><BR> <BR><BR>&nbsp;&nbsp;&nbsp;&nbsp;A::f() called.<BR><BR>&nbsp;&nbsp;&nbsp;&nbsp;C::f() called.<BR><BR> <BR><BR>&nbsp;&nbsp;&nbsp;&nbsp;关于析构函数中调用虚函数同构造函数一样,即析构函数所调用的虚函数是自身类的或者基类中实现的虚函数。<BR><BR> <BR><BR>&nbsp;&nbsp;&nbsp;&nbsp;一般要求基类中说明了虚函数后,派生类说明的虚函数应该与基类中虚函数的参数个数相等,对应参数的类型相同,如果不相同,则将派生类虚函数的参数的类型强制转换为基类中虚函数的参数类型。<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-06-17 18:36:13
<br>内容:虚函数是C++实现多态特性的关键<BR>哎呀,不好说这个,呵呵,书上写的最明白 :)
<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 + -