无法理解C++多态性与虚函数

Roth- 2012-11-11 03:39:54
如果一个派生类是有很多层的,即他的父类也是另一个类的子类
那么只要显示调用派生类的同名函数就可以直接用派生类的函数了
如a.c()
干嘛非要创意个父类指针然后用虚函数实现,自动选择指向的对象类型的那个函数
如p->c()
同名的不是可以重载的吗
例子
class A
{public:
void a();
};
void A::a()
{
cout<<'a'<<endl;
}
class B:public A
{public:
void a();
};
void B::a()
{
cout<<'b'<<endl;
}
void main()
{
B g;
g.a();
g.A::a();
system("pause");
}
...全文
250 8 打赏 收藏 转发到动态 举报
写回复
用AI写文章
8 条回复
切换为时间正序
请发表友善的回复…
发表回复
Emiyasstar__ 2012-11-11
  • 打赏
  • 举报
回复
虚函数可以实现调用接口一致,另外重载是相对同一个作用域而言的,你的那个例子只是覆盖,而不是重载
大尾巴猫 2012-11-11
  • 打赏
  • 举报
回复
c++多态性与虚函数是为了让代码的利用率更高。减少一些重复的甚至令人不愉快的代码。 举个简单的例子: 如果类A有个接口show()可以显示一些信息, 类B也有接口show()显示某些信息。 类A实例化了5个对象,类B实例化了5个对象。 显然,你要显示这10个对象的信息,你需要用2个数组去分别保存2种对象,用2个for循环完成show()的动作。 如果有更多的类呢,需要更多的数组和更多的for循环,有时还有很多层的if else嵌套来判断是哪个类。 重复写那些差不多同样的代码总是无趣的。 你现在可以用一个基类,定义个virtual show()的方法。 下面几个类共同继承这个基类,实现各自的show()。 你只需要开一个数组,保存这些类的对象的基类指针。 for循环也只要一个,用基类指针->show()可以显示所有对象的信息。 代码看起来更简洁更容易理解和维护。 当然也是有代价的,虚函数要查表,影响了一点点效率。
大尾巴猫 2012-11-11
  • 打赏
  • 举报
回复
5楼很好的例子。
wjain 2012-11-11
  • 打赏
  • 举报
回复
给你一个具体的例子你可以理解一下。 对于函数

bird_tweet
的目的是要鸟叫。 而具体要哪种鸟叫`~ 是由外部穿的鸟的种类决定的`~ 这样`只要是鸟`它总会有自己的叫法`~ 所以只要有了鸟的基类和bird_tweet函数`~ 你就可以听见各种鸟的叫`~ 无论有多少种鸟`只要保证是只会叫的鸟`~ 都可以通过bird_tweet来让它叫出来`~ 所以对于函数bird_tweet这个借口来说`~ 它无需做任何改变就可以发出各种鸟的叫声`~ 这部分还是需要你慢慢深入理解的`~ 学习的过程是漫长的`~ 希望我的这个例子对你有所帮助`~

/**
 * @file   test.cpp
 * @author Jain <Jain_Y@126.com>
 * @date   Sun Nov 11 17:32:24 2012
 * 
 * @brief  理解多态性与虚函数
 * 
 * 
 */

/** 
 * 定义一个鸟类,鸟会叫。但是鸟是一个物种的统称,所以对于鸟类没有具体的叫法,
 * 所以鸟类没有具体的对象,是一种抽象。
 * 
 */

#include <iostream>
using namespace std;

class CBird
{
public:
    CBird()
    {
        
    }

    virtual ~CBird()
    {
    
    }
    virtual void tweet() = 0;

};

/** 
 * 定义乌鸦类,乌鸦是一中鸟。
 * 乌鸦会按照乌鸦的叫法叫。
 * 
 */
class CCrow : public CBird
{
public:
    CCrow()
    {
        
    }
    virtual ~CCrow()
    {
        
    }
    virtual void tweet()
    {
        cout << "Crow tweer." << endl;
    }
};

/** 
 * 喜鹊类。
 * 喜鹊也有自己的叫法。
 * 
 */
class CMagpie : public CBird
{
public:
    CMagpie()
    {
    
    }
    
    virtual ~CMagpie()
    {
    
    }
    
    virtual void tweet()
    {
        cout << "Magpie tweer." << endl;
    }
};

void bird_tweet(CBird *bird)
{
    bird->tweet();
}


int main(int argc, char *argv[])
{
    // 我想听乌鸦叫
    CCrow crow;
    bird_tweet(&crow);
    CMagpie magpie;
    // 我想听喜鹊叫
    bird_tweet(&magpie);
    
    return 0;
}
Joseph_1118 2012-11-11
  • 打赏
  • 举报
回复
建议楼主去看《深入探索C++对象模型》这本书,搞清楚派生类的内存布局,虚表指针虚表等概念及实现。
wo1182929447 2012-11-11
  • 打赏
  • 举报
回复
我有时候也感觉一些很简单的,可以直接调用的方法,偏偏要写出一段很麻烦的代码来调用。求详解,谢谢
转角天边 2012-11-11
  • 打赏
  • 举报
回复
楼主试下这段代码,看看加虚函数和不加虚函数有什么区别

B g;
g.a();
A *a=new B;
a->a();
system("pause");
wangxuan375 2012-11-11
  • 打赏
  • 举报
回复
基类指针或引用是可以指向派生类对象的,你的实现是在派生类中隐藏了基类a()的实现。

A *p;
B bb;
p = &bb;
p->a();
按照你的实现这么使用,就会调用基类的a(),因为,你并不能保证A *p一定会指向基类。 public是一种'is a'继承。

64,685

社区成员

发帖
与我相关
我的任务
社区描述
C++ 语言相关问题讨论,技术干货分享,前沿动态等
c++ 技术论坛(原bbs)
社区管理员
  • C++ 语言社区
  • encoderlee
  • paschen
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
  1. 请不要发布与C++技术无关的贴子
  2. 请不要发布与技术无关的招聘、广告的帖子
  3. 请尽可能的描述清楚你的问题,如果涉及到代码请尽可能的格式化一下

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