Previous: Templates Up: C++ basics Next: Thermodynamic library in OpenFOAM
This is an automatically generated documentation by LaTeX2HTML utility. In case of any issue, please, contact us at info@cfdsupport.com.
Templates and inheritance
To make the language even more flexible, it is possible to combine the so far mentioned concepts of inheritance and templates. Imagine having a following two classes for representing pets dog and cat:
class dog { private: std::string name_; public: // constructor // just initialize the name dog( std::string name ) : name_(name) {} virtual void bark() const {std::cout << "Bark! Woof! Bark!\n";} // get dog's name std::string name() const {return name_;} }; class cat { private: std::string name_; public: // constructor // just initialize the name cat( std::string name ) : name_(name) {} virtual void meow() const {std::cout << "Meow! Meow! Meow!\n";} // get cat's name std::string name() const {return name_;} };
Now, the municipality has declared, that each dog has to be registered and have its own ID number. One way to do that is to extend the class, add new member to represent the ID, new getter function for the ID etc. But not every dog in the world is registered, we may want to keep registered and unregistered dogs separate. Solution is to create derived class registered_dog as follows:
class registered_dog : public dog { private: int ID_; public: // constructor registered_dog(int ID, std::string name) : dog(name), ID_(ID) {} int get_ID() const { return ID_; } };
The new derived class handles the ID for dogs, but if dog is not registered, we can still use the original class to represent it. Now, the municipality has also declared, that cats also have to be registered and have their ID. We might solve the problem similarly as for dogs, however the code will be practically the same for dogs and cats. The solution to the problem is to use template in conjunction with inheritance:
template class registered : public Animal { private: int ID_; public: // constructor // first initialize the animal // then ID registered(int ID, std::string name) : Animal(name), ID_(ID) {} int get_ID() const { return ID_; } };
The template class registered has template parameter Animal and is derived from it. This means, that it will be derived from whatever class we will instantiate it for. For example, instance registered will be deriver from dog, registered will be derived from cat. If there were more animals, we could use it for all of them. Basically for almost the same amount of code, we got double the functionality than in case of registered_dog. Following piece of code is demonstrating use of the template class registered in comparison with registered_dog:
int main() { // Max is registered_dog registered_dog max = registered_dog(1, "Max"); // Rex is registered registered rex = registered(2, "Rex"); // Oscar is a registered registered oscar = registered(3, "Oscar"); std::cout << "Our dog " << max.name() << " has ID " << max.get_ID() << " and barks like this:\n"; max.bark(); std::cout << "Our dog " << rex.name() << " has ID " << rex.get_ID() << " and barks like this:\n"; rex.bark(); std::cout << "Neighbours cat " << oscar.name() << " has ID " << rex.get_ID() << " and meows like this:\n"; oscar.meow(); return 0; }
The usage is practically the same. File with the example code can be found in training/cpp_tutorial in directory templatesVSInheritance in file main.cpp. The code can be compiled by following command:
# g++ main.cpp -o templatesInheritance
# x86_64w64-mingw32-g++ main.cpp -o templatesInheritance
Running the program will result in following output:
# ./templatesInheritance
# Our dog Max has ID 1 and barks like this:
# Bark! Woof! Bark!
# Our dog Rex has ID 2 and barks like this:
# Bark! Woof! Bark!
# Neighbours cat Oscar has ID 2 and meows like this:
# Meow! Meow! Meow!
Previous: Templates Up: C++ basics Next: Thermodynamic library in OpenFOAM