Inheritance for encapsulation. Some sort of design pattern.
Today we are going to see how inheritance can be used to hide implementation details.
We have
PersonInterface - Abstract class ( PersonInterface.{h,cpp} )
RealPerson - Derived from PersonInterface and implements PersonInterface.
(RealPerson.{h,cpp}
main.cpp - the main function.
PersonInterface.h
//
// PersonInterface.h
// InterfaceDemo
//
// Created by Mandar Vaidya on 10/05/2013.
// Copyright (c) 2013 Mandar Vaidya. All rights reserved.
//
#ifndef __InterfaceDemo__PersonInterface__
#define __InterfaceDemo__PersonInterface__
#include<string>
class PersonInterface {
public:
virtual ~PersonInterface(){};
virtual std::string name() const =0;
virtual std::string address() const=0;
//NOTE: I am returning a pointer.. it is bad idea instead I should have returned a shared_ptr.
// This is just to elaborate the concept.
//This function is a public function implementation inside the abstract class
//This returns the object of derived class refer. Effective C++ 3rd Ed. Item 31
// 1. This is a factory function.
// 2. This is public static function in base class or interface class that returns
// derived class object.
static PersonInterface* create(const std::string& name, const std::string& address);
};
#endif /* defined(__InterfaceDemo__PersonInterface__) */
PersonInterface.cpp
//
// PersonInterface.cpp
// InterfaceDemo
//
// Created by Mandar Vaidya on 10/05/2013.
// Copyright (c) 2013 Mandar Vaidya. All rights reserved.
//
#include "PersonInterface.h"
#include "RealPerson.h"
//NOTE: I am returning a pointer.. it is bad idea instead I should have returned a shared_ptr.
// This is just to elaborate the concept.
//This function is a public function implementation inside the abstract class
//This returns the object of derived class refer. Effective C++ 3rd Ed. Item 31
// 1. This is a factory function.
// 2. This is public static function in base class or interface class that returns
// derived class object.
PersonInterface* PersonInterface::create(const std::string& name, const std::string& address)
{
return new RealPerson(name,address);
}P
RealPerson.h
//
// RealPerson.h
// InterfaceDemo
//
// Created by Mandar Vaidya on 10/05/2013.
// Copyright (c) 2013 Mandar Vaidya. All rights reserved.
//
#ifndef __InterfaceDemo__RealPerson__
#define __InterfaceDemo__RealPerson__
#include "PersonInterface.h"
class RealPerson :public PersonInterface
{
public:
RealPerson(const std::string& name, const std::string& address);
virtual ~RealPerson();
virtual std::string name() const;
virtual std::string address() const;
private:
std::string theName;
std::string theAddress;
};
#endif /* defined(__InterfaceDemo__RealPerson__) */
RealPerson.cpp
//
// RealPerson.cpp
// InterfaceDemo
//
// Created by Mandar Vaidya on 10/05/2013.
// Copyright (c) 2013 Mandar Vaidya. All rights reserved.
//
#include "RealPerson.h"
RealPerson::RealPerson(const std::string& name, const std::string& address)
: theName(name), theAddress(address)
{
}
RealPerson::~RealPerson(){}
std::string RealPerson::name() const
{
return theName;
}
std::string RealPerson::address() const
{
return theAddress;
}
Main.cpp
//
// main.cpp
// InterfaceDemo
//
// Created by Mandar Vaidya on 10/05/2013.
// Copyright (c) 2013 Mandar Vaidya. All rights reserved.
//
#include <iostream>
#include "PersonInterface.h"
int main(int argc, const char * argv[])
{
PersonInterface* ptr = PersonInterface::create("MANDAR","31 Salders Court");
std::cout << "Name: " << ptr->name() << " Address: " << ptr->address();
delete ptr;
return 0;
}
Analysis:
- PersonInterface is an abstract class and provides the interface for personal details such as name and address etc.
- There are only interface methods declared as pure virtual in the base class. Note that member variables are not declared/ defined.
- Base class also has a static function that takes in parameters, which then creates and returns derived class object on heap.
- Note: Actually create function ( also called as factory method ) should return the shared pointer to enable RAII and prevent accidental memory leak in case object is not deleted. but this is a quick example hence I have got away with the pointer.
- RealPerson class is derived from PersonInterface and it defines its own private member variables. It also implements the interface provided by PersonInterface.
- It also provides public constructor so that base class's static function can create its object.
- If you now look at main.cpp It only depends on PersonInterface shown by including PersonInterface.h only. RealPerson is hidden from the main function and it's implementation can change any time as long as public interfaces remain same.
- As main function doesn't depend on the RealPerson, even if it changes, recompilation of main.cpp is not required only new object file is linked with main.obj. This way dependency is reduced.
- Also note that runtime polymorphism is in play as PersonInterface pointer is used to refer to RealPerson object.
- Also strongly note that both the destructors (base and derived) are marked as virtual so that runtime polymorphism works.
No comments:
Post a Comment