- Up type conversion
1 enum note {middleC,Csharp,Cflat}; 2 class Instrument { 3 public: 4 void play(note) const { 5 cout << "Instrument::play" << endl; 6 } 7 }; 8 9 class Wind: public Instrument { 10 public: 11 void play(note) const { 12 cout << "Wind::play" <<endl; 13 is } 14 }; 15 16 void ture (Instrument & I) { . 17 18 is i.play (MiddleC); . 19 } 20 is int main () 21 is { 22 is Wind FLUTE; 23 is Tune (FLUTE); 24 // final print is Instrument :: play, although the upward type conversion object belongs Wind, 25 // but inherited Wind Instrument, so ture (Instrument & i) is passed even Wind class, can convert up Instrument object class 26 is 27 }
The result becomes the virtual function is different
1 enum note {middleC,Csharp,Cflat}; 2 class Instrument { 3 public: 4 void play(note) const { 5 cout << "Instrument::play" << endl; 6 } 7 }; 8 9 class Wind: public Instrument { 10 public: 11 virtual void play(note) const { 12 cout << "Wind::play"<< endl; 13 is } 14 }; 15 16 void ture (Instrument & I) { . 17 18 is i.play (MiddleC); . 19 } 20 is int main () 21 is { 22 is Wind FLUTE; 23 is Tune (FLUTE); // final print the results for the Wind :: play, after adding the virtual keyword, you can ensure that inherit the scalability to ensure that the derived class has a function different from their own base class to achieve re-defined function. 24 }
- Pure abstract base class virtual function
In the design class, usually the base class as a standard interface derived class, generally do not create objects of the base class, to establish the basis of a template, it's derived classes to redefine the function of the function. Prohibits a pure virtual function call to the function by value abstract class, target slice occurs, by reference or pointer avoided.
1 enum note {middleC,Csharp,Cflat}; 2 class Instrument { 3 public: 4 virtual void play(note) const = 0; 5 virtual char* what() const = 0; 6 virtual void adjust(int) = 0; 7 }; 8 9 class Wind: public Instrument { 10 public: 11 void play(note) const 12 { 13 cout << "Wind::play" << endl; 14 } 15 char* what() const 16 { 17 return "Wind"; 18 19 } 20 void adjust(int) {} 21 }; 22 class Percussion : public Instrument { 23 public: 24 void play(note) const 25 { 26 cout << "Percussion::play" << endl; 27 } 28 char* what() const 29 { 30 return "Percussion"; 31 32 } 33 void adjust(int) {} 34 }; 35 class Stringed : public Instrument { 36 public: 37 void play(note) const 38 { 39 cout << "Stringed ::play" << endl; 40 } 41 char* what() const 42 { 43 return "Stringed"; 44 45 } 46 void adjust(int) {} 47 }; 48 class Brass : public Wind { 49 public: 50 void play(note) const 51 { 52 cout << "Brass ::play" << endl; 53 } 54 char* what() const 55 { 56 return "Brass"; 57 58 } 59 }; 60 class Woodwind : public Wind { 61 public: 62 void play(note) const 63 { 64 cout << "Woodwind ::play" << endl; 65 } 66 char* what() const 67 { 68 return "Woodwind"; 69 70 } 71 }; 72 void ture(Instrument& i) { 73 74 i.play(middleC); 75 } 76 void f(Instrument& i) 77 { 78 i.adjust(1); 79 } 80 int main() 81 { 82 Wind flute; 83 Percussion drum; 84 Stringed violin; 85 Brass fluge; 86 Wood wind recorder; 87 tune (flute); 88 tune (drum); 89 tune (violin); 90 tune (flight); 91 tune (recorder); 92 f (flight); 93 }
- Object Slice
Solve the multi-state, the base class of the object in question operate a derived class object, the object slice will not visit the base class derived class, can not make sense polymorphism.
1 class Pet { 2 string pname; 3 public: 4 Pet(const string& name) :pname(name) {} 5 virtual string name() const { return pname; } 6 virtual string description()const 7 { 8 return pname; 9 } 10 }; 11 12 class Dog : public Pet { 13 string factive; 14 public : 15 Dog ( const String & name, const String & Active): the Pet (name), Factive (Active) {} 16 String Description () { . 17 return Factive; 18 is } . 19 }; 20 is void Description (the Pet P) // passed so that the value, not the reference is not the address pointer 21 is { 22 is COUT << p.description () << endl; 23 is } 24 25 int main () 26 is { 27 the Pet P ( " Alfred" ); 28 Dog d ( " Fluffy " , " sleep " ); 29 description (p); 30 the Description (d); 31 // We hope description (p) appear Alfred results, description (d) occurs sleep results, 32 // but the end result is the actual description (d) the Fluffy appears, also called base class, 33 // not a derived class. because the process pass address values can not be changed. 34 }
- Overloading and redefine
When overloaded functions redefine a base class, the base class function will hide all the other functions of the overload, but when operation of the virtual function definition is not the same again. The following references and d4 is one difference.
1 class Base { 2 public: 3 virtual int f()const { 4 cout << "Base::f()"; 5 return 1; 6 } 7 virtual void f(string) const {} 8 virtual void g() const {} 9 }; 10 11 class Derived1 :public Base { 12 public: 13 void g() cont {} 14 }; 15 class Derived2 :public Base { 16 public: 17 int f() cont { 18 cout << "Derived2::f()"; 19 return 2; 20 } 21 }; 22 class Derived3 :public Base { 23 public: 24 /*void f() const { 25 cout << "Derived3::f()"; 26 return 3; 27 } * /// illegal, can not change the type of return 28 }; 29 class Derived4: public Base { 30 public : 31 is int F ( int ) {CONT 32 COUT << " Derived4 :: F () " ; 33 is return . 3 ; 34 is } 35 }; 36 int main () 37 [ { 38 is srting S ( " Hello " ); 39 Derived1 D1; 40 int X =d1.f (); 41 is d1.f (S); 42 is the Derived2 D2; 43 is X = d2.f (); 44 is // d2.f (S); Hide 45 Derived4 D4; 46 is X = d4.f ( . 1 ); 47 // X = d4.f (); hide 48 // d4.f (S); Hide 49 Base = & br D4; 50 // br.f (. 1); 51 is br.f (); 52 is br .F (S); // with opposite Derived4 d4 53 }