Inheritance, Polymorphism, and Virtual Functions

Inheritance and Derivation of classes can be accomplished to have code that is more object oriented and helps you optimize your code. Polymorphism can be accomplished using virtual functions to allow programs to decide which classes functions to use from their parents and children. These concepts can optimize your code in computer science and engineering as you create complex classes to develop your C++ project.

Inheritance and Derivation

To understand Inheritance and Derivation of children and parent classes, we will look at the following code which is a class called Microprocessor which represents the processor of a computer which is simply a component of what computers are made of.

#include <string>

class Microprocessor {
  public:
    Microprocessor(const std::string& Brand, const float& GHz, const std::string& Model);
    std::string& getBrand() const;
    std::string& getModel() const;
    std::string& displayAll() const;
    float& getGHz() const;
    void setGHz(const float& GHz);
    void setModel(const std::string& model);
    void setBrand(const std::string& brand);
  private:
    float m_GHz;
    std::string m_Brand;
    std::string m_Model;
};

Microprocessor::Microprocessor(const std::string& Brand, const float& GHz, const std::string& Model) {
  m_Brand = Brand;
  m_Model = Model;
  m_GHz = GHz;
}

std::string& Microprocessor::getBrand() const {
  return std::string("Microprocessor Brand: "+m_Brand);
}

std::string& Microprocessor::getModel() const {
  return std::string("Microprocessor Model: "+m_Model);
}

std::string& Microprocessor::displayAll() const {
  return std::string(getBrand()+"\n"+getModel()+"\n"+getGHz()+"\n");
}

float& Microprocessor::getGHz() const {
  return std::string("Microprocessor GigaHertz: "+m_GHz);
}

void setModel(const std::string& model){
  m_Model = model;
}
void setBrand(const std::string& brand){
  m_Brand = brand;
}
void setGHz(const float& GHz){
  m_GHz = GHz;
}

So we establish a class with public functions but private members m_Brand, m_Model, and m_GHz which are our member values for this processor class.

The Computer class is a representation of a computer, which has components such as a motherboard, a microprocessor, graphic card, and memory components like RAM and Harddisks.

class Computer : public Microprocessor, public RAM, public MotherBoard, public GraphicCard {
  public:
    Computer(const& std::string CompName, const& std::string Brand, const& std::MacAddress);
    std::string& getCompName() const;
    std::string& getMacAddress() const;
    std::string& getBrand() const;
    std::string& displayAll() const;
  private:
    std::string m_CompName;
    std::string m_MacAddress;
    std::string m_Brand;
}
Computer::Computer(const& std::string CompName, const& std::string Brand, const& std::MacAddress){
  m_CompName = CompName;
  m_MacAddress = MacAddress;
  m_Brand = Brand;  
}

std::string& getCompName() const {
  return std::string("Comp Name: "+m_CompName);
}
std::string& getBrand() const {
  return std::string("Comp Brand: "+m_Brand);
}
std::string& displayAll() const {
  return std::string(m_CompName+"\n"+m_Brand+"\n"+m_MacAddress+"\n");
}
std::string& getMacAddress() const {
  return std::string("Comp Name: "+m_MacAddress);
}

We've declared the parents of Computer which are the Motherboard, RAM, Microprocessor and a number of other components. We use the colon operator and public to indicate that we are inheriting all the public members of the parent classes.

So what can we do now? Well we can getBrand() on Computer class to learn the microprocessor brand.

Computer mycomp("InfernoPC", "HP", "01:23:45:67:89:ab");
mycomp.getCompName() // will print "Comp Name: InfernoPC"
mycomp.setGHz(2.26);
mycomp.setModel("P8400");
mycomp.setBrand("Intel");
// well now we've set all the Microprocessor fields for Computer.
// We actually edited the basic Microprocessor inside the Computer class
// which had inherited all the Microprocessor public functions.
string s;
s = mycomp.displayAll(); // guess what this displays
cout << s << endl;

So now we've established our Computer and Microprocessor information in our computer.

What do you think displayAll() will display? Well both Microprocessor and Computer class has a function named displayAll() so which one does the code choose?

Well it's going to display the Microprocessor stuff, not the Computer displayAll().

What if you wanted to display the displayAll() on Computer? This leads us to our next section.

Polymorphism and Virtual keyword

Well in our original Microprocessor class, if we declared the displayAll() function as "virtual std::string& displayAll() const;" then the same code will display the Computer class's displayAll() instead of the Microprocessor class. It allows other classes to override the virtual function.

We can also do something interesting with the inherited code. If we had a copy constructor, such as "Microprocessor(Microprocessor* t);", we could do Microprocessor(&mycomp); to add the all information in mycomp (the Computer class) to the Microprocessor. In other words, the Computer class can behave exactly like a Microprocessor class. It can transform itself, or polymorph into whatever the type is as long as it inherits the same class.

This is called polymorphism, the ability to convert a Computer class into a Microprocessor class, because the Computer class inherits a Microprocessor so it IS a Microprocessor anyway.

Post new comment

The content of this field is kept private and will not be shown publicly. If you have a Gravatar account associated with the e-mail address you provide, it will be used to display your avatar.