When base class is used to point to derived class, base class pointer calls overridden base-class methods, if there are any base class virtual method re-implementations in the derived class. Virtual functions in C++ help to transfer a specific behavior in the base class to derived class by declaring the function virtual in the base class. Derived is free to re-implement base class virtual functions.
If the derived class does not provide any implementation for the base class virtual functions then the base class virtual functions are called. This is not always the expected behavior because base class virtual functions are declared to be overridden in the derived class.
Following sample project created by qt creator and contains following files:
1- VirtualFunctions.pro
2- main.cpp
3- abstractservice.h
4- abstractservice.cpp
5- activityservice.h
6- activityservice.cpp
7- userservice.h
8- userservice.cpp
VirtualFunctions.pro file contains project configuration.
TARGET = VirtualFunctions CONFIG += console TEMPLATE = app SOURCES += main.cpp \ abstractservice.cpp \ userservice.cpp \ activityservice.cpp HEADERS += \ abstractservice.h \ userservice.h \ activityservice.h
abstractservice.h is the base class that contains virtual functions.
#ifndef ABSTRACTSERVICE_H #define ABSTRACTSERVICE_H #include <stdio.h> class AbstractService { public: AbstractService(); virtual ~AbstractService(); // calls both base and derived dest // prevents memory leaks virtual void insertRecord(); virtual void selectRecord(); virtual void deleteRecord(); virtual void updateRecord(); }; #endif // ABSTRACTSERVICE_HIn the base class abstractservice.h destructor is also defined virtual otherwise derived class destructor is not called at object deletion.
abstractservice.cpp is the base class implementation file that contains implementations for virtual functions, constructor and destructor.
#include "abstractservice.h" AbstractService::AbstractService() { printf("AbstractService::AbstractService called\n"); } AbstractService::~AbstractService() { printf("AbstractService::~AbstractService called\n"); } void AbstractService::insertRecord() { printf("AbstractService::insertRecord called\n"); } void AbstractService::selectRecord() { printf("AbstractService::selectRecord called\n"); } void AbstractService::deleteRecord() { printf("AbstractService::deleteRecord called\n"); } void AbstractService::updateRecord() { printf("AbstractService::updateRecord called\n"); }userservice.h is the first derived class that contains its own implementations for the virtual functions that are declared in the base class abstractservice.
#ifndef USERSERVICE_H #define USERSERVICE_H #include "abstractservice.h" class UserService : public AbstractService { public: UserService(); ~UserService(); void insertRecord(); void selectRecord(); void deleteRecord(); void updateRecord(); }; #endif // USERSERVICE_Huserservice.cpp contains implementation details for the base class virtual functions.
#include "userservice.h" UserService::UserService() { printf("UserService::UserService called\n"); } UserService::~UserService() { printf("UserService::~UserService called\n"); } void UserService::insertRecord() { printf("UserService::insertRecord called\n"); } void UserService::selectRecord() { printf("UserService::selectRecord called\n"); } void UserService::deleteRecord() { printf("UserService::deleteRecord called\n"); } void UserService::updateRecord() { printf("UserService::updateRecord called\n"); }activityservice.h is the second derived class that re-declares base class virtual functions in its header.
#ifndef ACTIVITYSERVICE_H #define ACTIVITYSERVICE_H #include "abstractservice.h" class ActivityService : public AbstractService { public: ActivityService(); ~ActivityService(); void insertRecord(); void selectRecord(); void deleteRecord(); void updateRecord(); }; #endif // ACTIVITYSERVICE_Hactivityservice.cpp file contains implementation details for the base class virtual functions.
#include "activityservice.h" ActivityService::ActivityService() { printf("ActivityService::ActivityService called\n"); } ActivityService::~ActivityService() { printf("ActivityService::~ActivityService called\n"); } void ActivityService::insertRecord() { printf("ActivityService::insertRecord called\n"); } void ActivityService::selectRecord() { printf("ActivityService::selectRecord called\n"); } void ActivityService::deleteRecord() { printf("ActivityService::deleteRecord called\n"); } void ActivityService::updateRecord() { printf("ActivityService::updateRecord called\n"); }Both of the derived classes provide their own implementations for the virtual functions declared in the base class abstractservice.
main.cpp file contains a main function that is creating different base class pointers which are pointing to derived class objects.
#include "userservice.h" #include "activityservice.h" int main(int argc, char *argv[]) { UserService *userServicePtr = new UserService; userServicePtr->insertRecord(); userServicePtr->selectRecord(); userServicePtr->updateRecord(); userServicePtr->deleteRecord(); delete userServicePtr; printf("\n"); AbstractService *abstractServiceObjPtr = new AbstractService; abstractServiceObjPtr->insertRecord(); abstractServiceObjPtr->selectRecord(); abstractServiceObjPtr->updateRecord(); abstractServiceObjPtr->deleteRecord(); delete abstractServiceObjPtr; printf("\n"); // base class pointer to derived class object char option = 'a'; AbstractService *serviceObjPtr; if( option == 'u' ) { serviceObjPtr = new UserService; serviceObjPtr->insertRecord(); serviceObjPtr->selectRecord(); serviceObjPtr->updateRecord(); serviceObjPtr->deleteRecord(); delete serviceObjPtr; printf("\n"); } else if( option == 'a' ) { serviceObjPtr = new ActivityService; serviceObjPtr->insertRecord(); serviceObjPtr->selectRecord(); serviceObjPtr->updateRecord(); serviceObjPtr->deleteRecord(); delete serviceObjPtr; printf("\n"); } return 0; }At runtime base class pointer serviceObjPtr points to either UserService instance or ActivityService instance.
Console output also shows the order for object creation and destruction.
No comments:
Post a Comment