C++ 虚函数的一个应用场景及其重要性


虚函数是C++ 语言的一个重要特性,其原理及实现方法参见 http://blog.csdn.net/digu/article/details/1892581

主要用来实现所谓的多态……我个人水平低,对于这些东西一直是没有非常的理解。

随着使用C++的时间变长,接触的代码变多,越来越多地感觉到虚函数的重要作用。这里我列举出一个例子,供大家学习。

首先我假定读者对于虚函数是有一定了解的,最起码虚函数是什么,基本作用是什么要知道,如果不知道请参看上面的链接,或任何一本讲C++的书。


开始:例子来源于qgis的C++插件

——————————————————————————————————————————————————

一、插件类 的基类

class QgisPlugin

在类定义中请注意 几个纯虚函数:

    virtual void initGui() = 0;
    //! Unload the plugin and cleanup the GUI
    virtual void unload() = 0;

这两个函数实现的是插件图形初始化以及插件卸载。

QgisPlugin.h

class QgisPlugin
{
  public:
    QgisPlugin( QString const & name = "",
                QString const & description = "",
                QString const & category = "",
                QString const & version = "",
                PLUGINTYPE const & type = MAPLAYER )
        : mName( name ),
        mDescription( description ),
        mCategory( category ),
        mVersion( version ),
        mType( type )
    {}

    virtual ~QgisPlugin()
    {}

    //! Get the name of the plugin
    QString const & name() const
    {
      return mName;
    }

    QString       & name()
    {
      return mName;
    }

    //! Version of the plugin
    QString const & version() const
    {
      return mVersion;
    }

    //! Version of the plugin
    QString & version()
    {
      return mVersion;
    }

    //! A brief description of the plugin
    QString const & description() const
    {
      return mDescription;
    }

    //! A brief description of the plugin
    QString       & description()
    {
      return mDescription;
    }

    //! Plugin category
    QString const & category() const
    {
      return mCategory;
    }

    //! Plugin category
    QString       & category()
    {
      return mCategory;
    }

    //! Plugin type, either UI or map layer
    QgisPlugin::PLUGINTYPE const & type() const
    {
      return mType;
    }


    //! Plugin type, either UI or map layer
    QgisPlugin::PLUGINTYPE       & type()
    {
      return mType;
    }

    /// function to initialize connection to GUI
    virtual void initGui() = 0;

    //! Unload the plugin and cleanup the GUI
    virtual void unload() = 0;

  private:

    /// plug-in name
    QString mName;

    /// description
    QString mDescription;

    /// category
    QString mCategory;

    /// version
    QString mVersion;

 
}; // class QgisPlugin


二、 继承自QgisPlugin的插件类 ClientWindow

ClientWindow继承了QgisPlugin

实现了 initGui(); 和 unload(); 

ClientWindow.h

class ClientWindow: public QObject, public QgisPlugin
{
    Q_OBJECT
  public:


    ClientWindow( QgisInterface * theInterface );
    //! Destructor
    virtual ~ClientWindow();
  public slots:
    //! init the gui
    virtual void initGui();
    //! Show the dialog box
    void run();
    //! unload the plugin
    void unload();
    //! show the help document
    void help();

  private:

    int mPluginType;
    //! Pointer to the QGIS interface object
    QgisInterface *mQGisIface;
    //!pointer to the qaction for this plugin
    QAction * mQActionPointer;

	msgsprite::cMsgSprite *msg;
  
};

ClientWindow.cpp

在这里面实现了这2个函数。

void ClientWindow::initGui()
{
  // Create the action for tool
  mQActionPointer = new QAction( QIcon( ":/clientwindow/clientwindow.png" ), tr( "client window" ), this );
  // Set the what's this text
  mQActionPointer->setToolTip(tr( "即时通讯" ));
  // Connect the action to the run
  connect( mQActionPointer, SIGNAL( triggered() ), this, SLOT( run() ) );
  // Add the icon to the toolbar
  mQGisIface->addToolBarIcon( mQActionPointer );
  mQGisIface->addPluginToMenu( tr( "&show client window" ), mQActionPointer );

}

// Unload the plugin by cleaning up the GUI
void ClientWindow::unload()
{
  // remove the GUI
  mQGisIface->removePluginMenu( "&show client window", mQActionPointer );
  mQGisIface->removeToolBarIcon( mQActionPointer );
  delete mQActionPointer;
}

三、主程序中的插件加载过程

在主程序中,cf是生成插件实例的函数,返回new出来的一个插件实例指针。

通过调用QgisPlugin *类型的基类指针pl->initGui()来调用插件中的initGui()函数。

        QgisPlugin *pl = cf( mQgisInterface );
        if ( pl )
        {
          pl->initGui();
         }

------------------------------------------------------------------------------------------------------------------------------------------------------------

不知道您看明白了没有,再总结一下:


class QgisPlugin 是基类,其中有虚函数

virtual void initGui() = 0;
virtual void unload() = 0;

插件类class ClientWindow继承了QgisPlugin 并实现了这两个函数

主程序通过一个QgisPlugin * 基类指针 pl->调用initGui(),这个时候调用的函数其实是ClientWindow中的initGui()函数。

这就实现了多态,也就是说插件类可能有多种,只要是继承了QgisPlugin 的都要实现这两个虚函数,而主程序中不需要知道具体的类到底是什么,只需要用一个类似于接口的基类QgisPlugin 指针可调用子类(在这里是一个插件)中的相关的函数。

这就是虚函数的功劳!除此之外不使用虚函数的话,你要如何实现呢?




  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

路边闲人2

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值