#include <iostream> #include <vector> using namespace std; // Animal attribute/property is common between Cow and Dog, hence this is the interface // that contains pure virtual functions of the property that is common to Cow and Dog // Since this is pure abstract class (since it has a pure virtual function), this class // cannot be instantiated. class Animal { public: virtual void Speak() const = 0; }; // Note: // You can have an implementation of a pure virtual function. // A derived class can explicitly call the base class implementation (if access permissions are allow it) // by using a fully-scoped name (by calling Animal::Speak(), if Animal::Speak() is public or protected (i.e. not private). // The use case can be when there's a more-or-less reasonable default behavior, but the class // designed wants that sort-of-default behavior to be invoked only explicitly. // It can also be the case what you want derived classes to always perform their own work but also be able to call a common set of functionality. // The other use could be for the case when you want to create a pure abstract class, but it does not have a pure virtual function. // In that case you can make the destructor a pure abstract method and create the implementation for the destructor. // Note that even though it's permitted by the language, it's not something that I see commonly used // (and the fact that it can be done seems to surprise most C++ programmers, even experienced ones). void Animal::Speak() const { cout << "Make some noise" << endl; } class Cow : public Animal { public: void Speak() const; }; void Cow::Speak() const { cout << "Moo" << endl; } class Dog : public Animal { public: void Speak() const; }; void Dog::Speak() const { cout << "Woof" << endl; } void Speak(const Animal& animal) // 1. Since we are passing a const reference, this can only call a const member function. { // So we will have to make Animal::Speak() const and in turn Cow::Speak() and Dog::Speak() const animal.Speak(); // 2. Passing a non const reference will let you modify Animal } // 3. Passing by value will lead to object slicing int main(int argc, char *argv[]) { Cow myCow; Dog myDog; vector<Animal*> animalVec; // You can't instantiate abstract classes, thus a vector of abstract classes can't work. // You can however use a vector of pointers to abstract classes. // Also storing by value i.e. vector<Animal> animalVec; will lead to object slicing animalVec.push_back(&myCow); animalVec.push_back(&myDog); for(vector<Animal*>::iterator iter = animalVec.begin(); iter != animalVec.end(); ++iter) { Speak(**iter); } system("PAUSE"); return EXIT_SUCCESS; }Output: Moo Woof Press any key to continue . . .
Thursday, September 11, 2014
C++ Interface Example
Subscribe to:
Post Comments (Atom)
No comments:
Post a Comment