虚函数是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
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 指针可调用子类(在这里是一个插件)中的相关的函数。
这就是虚函数的功劳!除此之外不使用虚函数的话,你要如何实现呢?