C++ inheritance examples
1.C++继承经典例子
1 #include <iostream> 2 using namespace std; 3 class Base 4 { 5 private: 6 int b_number; 7 public: 8 Base(){} 9 Base(int i) : b_number(i) { } 10 int get_number() { return b_number; } 11 void print() { cout << b_number << endl; } 12 }; 13 14 class Derived : public Base 15 { 16 private: 17 int d_number; 18 public: 19 // constructor, initializer used to initialize the base part of a Derived object. 20 Derived(int i, int j) : Base(i), d_number(j) { }; 21 // a new member function that overrides the print( ) function in Base 22 void print() 23 { 24 cout << get_number() << " "; 25 // access number through get_number( ) 26 cout << d_number << endl; 27 } 28 }; 29 int main() 30 { 31 Base a(2); 32 Derived b(3, 4); 33 cout << "a is "; 34 a.print(); // print( ) in Base 35 cout << "b is "; 36 b.print(); // print( ) in Derived 37 cout << "base part of b is "; 38 b.Base::print(); // print( ) in Base 39 return 0; 40 }
2.
1 #include <iostream> 2 #include <cmath> 3 using namespace std; 4 5 class Point 6 { 7 private: 8 double x; 9 double y; 10 public: 11 Point(double i, double j) : x(i), y(j) { } 12 void print() const 13 { 14 cout << "(" << x << ", " << y << ")"; 15 } 16 }; 17 18 class Figure 19 { 20 private: 21 Point center; 22 public: 23 Figure(double i = 0, double j = 0) : center(i, j) { } 24 25 Point& location() 26 { 27 return center; 28 } // return an lvalue 29 void move(Point p) 30 { 31 center = p; 32 draw(); 33 } 34 virtual void draw() = 0; // draw the figure 35 virtual void rotate(double) = 0; 36 // rotate the figure by an angle 37 }; 38 39 class Circle : public Figure 40 { 41 private: 42 double radius; 43 public: 44 Circle(double i = 0, double j = 0, double r = 0) : Figure(i, j), radius(r) { } 45 void draw() 46 { 47 cout << "A circle with center "; 48 location().print(); 49 cout << " and radius " << radius << endl; 50 } 51 void rotate(double) 52 { 53 cout << "no effect./n"; 54 } // must be defined 55 }; 56 57 class Square : public Figure 58 { 59 private: 60 double side; // length of the side 61 double angle; // the angle between a side and the x-axis 62 public: 63 Square(double i = 0, double j = 0, double d = 0, double a = 0) : Figure(i, j), side(d), angle(a) { } 64 void draw() 65 { 66 cout << "A square with center "; 67 location().print(); 68 cout << " side length " << side << ".\n" 69 << "The angle between one side and the X-axis is " << angle << endl; 70 } 71 void rotate(double a) 72 { 73 angle += a; 74 cout << "The angle between one side and the X-axis is " << angle << endl; 75 } 76 void vertices() 77 { 78 cout << "The vertices of the square are:\n"; 79 // calculate coordinates of the vertices of the square 80 } 81 }; 82 83 int main() 84 { 85 Circle c(1, 2, 3); 86 Square s(4, 5, 6); 87 Figure *f = &c, &g = s;//f是指针,g是引用。 88 f->draw(); 89 f->move(Point(2, 2)); 90 g.draw(); 91 g.rotate(1); 92 93 s.vertices(); 94 // Cannot use g here since vertices( ) is not a member of Figure. 注意!!!!!! 95 //(g是Figure类型的,而vertices是Square派生类特有的。所以通过Figure类型的对象访问不到vertices) 96 return 0; 97 }
3.1 没有虚析构函数,继承类没有析构
1 #include <iostream> 2 #include <string> 3 using namespace std; 4 5 class Thing 6 { 7 public: 8 virtual void what_Am_I() { cout << "I am a Thing.\n"; } 9 ~Thing(){ cout << "Thing destructor" << endl; } 10 }; 11 class Animal : public Thing 12 { 13 public: 14 virtual void what_Am_I() { cout << "I am an Animal.\n"; } 15 ~Animal(){ cout << "Animal destructor" << endl; } 16 }; 17 18 int main() 19 { 20 Thing *t = new Thing; 21 Animal*x = new Animal; 22 Thing* array[2]; 23 array[0] = t; // base pointer 24 array[1] = x; 25 for (int i = 0; i<2; i++) 26 array[i]->what_Am_I(); 27 delete array[0]; 28 delete array[1]; 29 return 0; 30 }
3.2.
1 #include <iostream> 2 #include <string> 3 using namespace std; 4 5 class Thing 6 { 7 public: 8 virtual void what_Am_I() { cout << "I am a Thing.\n"; } 9 ~Thing(){ cout << "Thing destructor" << endl; } 10 }; 11 12 class Animal : public Thing 13 { 14 public: 15 virtual void what_Am_I() { cout << "I am an Animal.\n"; } 16 ~Animal(){ cout << "Animal destructor" << endl; } 17 }; 18 19 void main() 20 { 21 Thing t; 22 Animal x; 23 Thing* array[2]; 24 array[0] = &t; // base pointer 25 array[1] = &x; 26 for (int i = 0; i<2; i++) array[i]->what_Am_I(); 27 return; 28 }
与上面的3.1对比。两个程序只有main函数不一样。原因大概是3.1中定义的是指针,如Thing* t=new Thing。而3.2中定义的是对象,如Thing t。对象消亡时会自动调用析构函数。指针的话需要自己去delete。所以做项目时最好用智能指针,因为能自动垃圾回收。
4.多继承
1 #include <iostream> 2 using namespace std; 3 4 class A 5 { 6 private: 7 int a; 8 public: 9 A(int i) : a(i) { } 10 virtual void print() { cout << "a: " << a << endl; } 11 int get_a() { return a; } 12 }; 13 14 class B 15 { 16 private: 17 int b; 18 public: 19 B(int j) : b(j) { } 20 void print() { cout << "b: " << b << endl; } 21 int get_b() { return b; } 22 }; 23 24 class C : public A, public B 25 { 26 int c; 27 public: 28 C(int i, int j, int k) : A(i), B(j), c(k) { } 29 void print() 30 { 31 cout << "c_print begin" << endl; 32 A::print(); B::print(); 33 cout << "c: " << c << endl; 34 cout << "c_print end" << endl; 35 } 36 // use print( ) with scope resolution 37 void get_ab() { cout << "c-get_ab: " << get_a() << " " << get_b() << endl; } 38 // use get_a( ) and get_b( ) without scope resolution 39 }; 40 41 int main() 42 { 43 C x(5, 8, 10); 44 A* ap = &x; 45 B* bp = &x; 46 ap->print(); // use C::print( ); 47 bp->print(); // use B::print( ); 48 // bp -> A::print( ); // as if x is inherited from B only, 49 // cannot access A::print( ); 50 x.A::print(); // use A::print( ); 51 x.get_ab(); 52 return 0; 53 }
5.共同基类的多继承
1 #include <iostream> 2 using namespace std; 3 4 class R 5 { 6 int r; 7 public: 8 R(int anInt){ r = anInt; }; 9 void printOn(){ cout << "r=" << r << endl; }; 10 }; 11 12 class A : public R 13 { 14 int a; 15 public: 16 A(int int1, int int2) :R(int2){ a = int1; }; 17 }; 18 19 class B : public R 20 { 21 int b; 22 public: 23 B(int int1, int int2) :R(int2){ b = int1; }; 24 }; 25 26 class C : public A, public B 27 { 28 int c; 29 public: 30 C(int int1, int int2, int int3) :A(int2, int3), B(int2, int3){ c = int1; } 31 }; 32 33 int main() 34 { 35 int i; 36 R rr(10); 37 A aa(20, 30); 38 B bb(40, 50); 39 C cc(5, 7, 9); 40 rr.printOn(); 41 aa.printOn(); //inherits R printOn 42 bb.printOn(); //inherits R printOn 43 //cc.printOn(); //would give error 44 return 0; 45 }
6.虚基类
1 #include <iostream> 2 using namespace std; 3 4 class R 5 { 6 int r; 7 public: 8 R(int x = 0) : r(x) { } // constructor in R 9 void f(){ cout << "r=" << r << endl; } 10 void printOn(){ cout << "printOn R=" << r << endl; } 11 }; 12 13 class A : public virtual R 14 { 15 int a; 16 public: 17 A(int x, int y) : R(x), a(y) { } // constructor in A 18 void f(){ cout << "a=" << a << endl; R::f(); } 19 }; 20 21 class B : public virtual R 22 { 23 int b; 24 public: 25 B(int x, int z) : R(x), b(z) { }// constructor in B 26 void f(){ cout << "b=" << b << endl; R::f(); } 27 }; 28 29 class C : public A, public B 30 { 31 int c; 32 public: 33 // constructor in C, which constructs an R object first 34 C(int x, int y, int z, int w) : R(x), A(x, y), B(x, z), c(w) { } 35 void f(){ cout << "c=" << c << endl; A::f(); B::f(); } 36 }; 37 38 int main() 39 { 40 R rr(1000); 41 A aa(2222, 444); 42 B bb(3333, 111); 43 C cc(1212, 345, 123, 45); 44 cc.printOn(); //uses R printOn but only 1 R..no ambiguity 45 cc.f(); // shows multiple call of the R::f() 46 return 0; 47 }
7.
1 #include <iostream> 2 using namespace std; 3 4 class R 5 { 6 int r; 7 public: 8 R(int x = 0) : r(x) { } // constructor in R 9 void f(){ cout << "r=" << r << endl; } 10 }; 11 12 class A : virtual public R 13 { 14 int a; 15 protected: 16 void fA(){ cout << "a=" << a << endl; }; 17 public: 18 A(int x, int y) : R(x), a(y) { } // constructor in A 19 void f() { fA(); R::f(); } 20 }; 21 22 class B : virtual public R 23 { 24 int b; 25 protected: 26 void fB(){ cout << "b=" << b << endl; }; 27 public: 28 B(int x, int y) : R(x), b(y) { } // constructor in A 29 void f() { fB(); R::f(); } 30 }; 31 32 class C : public A, public B 33 { 34 int c; 35 protected: 36 void fC(){ cout << "c=" << c << endl; }; 37 public: 38 C(int x, int y, int z, int w) : R(x), A(x, y), B(x, z), c(w) { } 39 void f() 40 { 41 R::f(); // acts on R stuff only 42 A::fA(); //acts on A stuff only 43 B::fB(); // acts on B stuff only 44 fC(); // acts on C stuff only 45 } 46 }; 47 48 void main() 49 { 50 R rr(1000); 51 A aa(2222, 444); 52 B bb(3333, 111); 53 C cc(1212, 345, 123, 45); 54 cc.f(); 55 }
8.私有继承
1 #include <iostream> 2 using namespace std; 3 4 class Base 5 { 6 private: 7 int priv; 8 protected: 9 int prot; 10 int get_priv() { return priv; } 11 public: 12 int publ; 13 Base(); 14 Base(int a, int b, int c) : priv(a), prot(b), publ(c) { } 15 int get_prot() { return prot; } 16 int get_publ() { return publ; } 17 }; 18 19 class Derived1 : private Base // private inheritance 20 { 21 public: 22 Derived1(int a, int b, int c) : Base(a, b, c) { } 23 int get1_priv() { return get_priv(); } 24 // priv not accessible directly 25 int get1_prot() { return prot; } 26 int get1_publ() { return publ; } 27 }; 28 29 class Leaf1 : public Derived1 30 { 31 public: 32 Leaf1(int a, int b, int c) : Derived1(a, b, c) { } 33 void print() 34 { 35 cout << "Leaf1 members: " << get1_priv() << " " 36 // << get_priv( ) // not accessible 37 << get1_prot() << " " 38 // << get_prot( ) // not accessible 39 // << publ // not accessible 40 << get1_publ() << endl; 41 } // data members not accessible. get_ functions in Base not accessible 42 }; 43 44 class Derived2 : protected Base // protected inheritance 45 { 46 public: 47 Derived2(int a, int b, int c) : Base(a, b, c) { } 48 }; 49 50 class Leaf2 : public Derived2 51 { 52 public: 53 Leaf2(int a, int b, int c) : Derived2(a, b, c) { } 54 void print() 55 { 56 cout << "Leaf2 members: " << get_priv() << " " 57 // << priv // not accessible 58 << prot << " " 59 << publ << endl; 60 } // public and protected data members accessible. get_ functions in Base accessible. 61 }; 62 63 class Derived3 : public Base // public inheritance 64 { 65 public: 66 Derived3(int a, int b, int c) : Base(a, b, c) { } 67 }; 68 69 class Leaf3 : public Derived3 70 { 71 public: 72 Leaf3(int a, int b, int c) : Derived3(a, b, c) { } 73 void print() 74 { 75 cout << "Leaf3 members: " << get_priv() << " " 76 << prot << " " 77 << publ << endl; 78 } // public and protected data members accessible. get_ functions in Base accessible 79 }; 80 81 int main() 82 { 83 Derived1 d1(1, 2, 3); 84 Derived2 d2(4, 5, 6); 85 Derived3 d3(7, 8, 9); 86 // cout << d1.publ; // not accessible 87 // cout << d1.get_priv( ); // not accessible 88 // cout << d2.publ; // not accessible 89 // cout << d2.get_priv( ); // not accessible 90 cout << d3.publ; // OK 91 cout << d3.get_prot(); // OK 92 Leaf1 lf1(1, 2, 3); 93 Leaf2 lf2(4, 5, 6); 94 Leaf3 lf3(7, 8, 9); 95 // cout << lf1.publ << endl; // not accessible 96 // cout << lf2.publ << endl; // not accessible 97 cout << lf3.publ << endl; // OK 98 return 0; 99 }
total:
452 453 454 多级继承 455 // Point-Circle-Cylinder 456 #include <iostream.h> 457 // THE POINT CLASS 458 class Point 459 { 460 friend ostream & operator<<(ostream &,Point &); 461 public: 462 463 // constructor 464 Point (double xval =0, double yval=0 ) 465 { x=xval; y=yval;}; 466 protected: // accessed by derived class 467 double x; 468 double y; 469 }; 470 ostream & operator << (ostream & os, 471 Point & apoint) 472 { 473 cout <<" Point:X:Y: "<<apoint.x << "," 474 << apoint.y<< "/n"; 475 return os; 476 } 477 //The Circle class inherits from class Point 478 class Circle : public Point 479 { 480 friend ostream & operator<<(ostream &,Circle&); 481 public: 482 Circle (double r=0,double xval=0,double yval=0) 483 :Point(xval,yval), radius(r) 484 { 485 //radius = r; 486 } 487 double area() 488 { 489 return (3.14159* radius *radius); 490 } 491 protected: 492 double radius; 493 }; 494 495 //note casting circle to point 496 ostream & operator <<(ostream & os, Circle & aCircle) 497 { 498 cout<< "Circle:radius:" << aCircle.radius; 499 os<< aCircle.x << "/n"; 500 os<< aCircle.y << "/n"; 501 return os; 502 } 503 // THE CYLINDER CLASS 504 class Cylinder : public Circle 505 { 506 friend ostream & operator << (ostream & ,Cylinder &); 507 public: 508 Cylinder (double hv=0,double rv=0, 509 double xv=0,double yv=0 ) 510 : Circle( xv,yv,rv) 511 { 512 height = hv; 513 } 514 double area ( ); 515 protected: // may have derived classes 516 double height; 517 }; 518 double Cylinder :: area ( ) 519 { // Note that cylinder area uses Circle area 520 return 2.0* Circle::area() + 2.0*3.14159* radius*height; 521 } 522 ostream & operator << (ostream & os, 523 Cylinder & acylinder) 524 { 525 cout << "cylinder dimensions: "; 526 cout << "x: " <<acylinder.x; 527 cout << " y: " <<acylinder.y ; 528 cout << " radius: " <<acylinder.radius ; 529 cout << " height: " <<acylinder.height 530 << endl; 531 return os; 532 } 533 int main(void) 534 { 535 Point p(2,3); 536 Circle c(7,6,5); 537 Cylinder cyl(10,11,12,13); 538 cout << p; 539 cout << c; 540 cout << "area of cirle:" << c.area() << endl; 541 cout<< cyl; 542 cout<<"area of cylinder:"<< cyl.area()<<endl ; 543 cout<<"area of cylinder base is " 544 << cyl.Circle::area() << endl; 545 return 0; 546 } 547 548 549 protected 访问控制属性在继承的意义 550 551 //Example of treating derived class object as base class objects. Point------Circle 552 #include <iostream.h> 553 // THE POINT CLASS 554 class Point 555 { 556 friend ostream & operator<<(ostream &,Circle&); 557 public: 558 Point (double xval =0, double yval=0 ) { x=xval; y=yval;}; 559 public: 560 void print() 561 { 562 cout <<" Point:X:Y: "<<x << "," <<y<< "/n"; 563 } 564 protected: // accessed by derived class 565 double x; double y; 566 }; 567 ostream & operator << (ostream & os, Point & apoint) 568 { 569 cout <<" Point:X:Y: "<<apoint.x << ","<< apoint.y<< "/n"; 570 return os; 571 } 572 573 //The Circle class inherits from class Point 574 class Circle : public Point 575 { 576 friend ostream & operator<<(ostream &,Circle&); 577 public: 578 Circle (double r=0,double xval=0,double yval=0):Point(xval,yval) 579 { radius = r;}; 580 void print() 581 { 582 cout<< "Circle:radius:" <<radius<<endl; 583 cout <<" Point:X:Y: "<<x << "," <<y<< "/n"; 584 } 585 double area() 586 { return (3.14159* radius *radius);}; 587 protected: 588 double radius; 589 }; 590 //note casting circle to point 591 ostream & operator <<(ostream & os, Circle & aCircle) 592 { 593 cout<< "Circle:radius:" << aCircle.radius; 594 cout<< (Point) aCircle << "/n"; 595 return os; 596 } 597 598 //We will look at a few main programs based on previous class definitions. Casting and assignments 599 void main (void ) 600 { 601 Point p(2,3); cout <<"Point P= "<< p; 602 Point pp(0,0); cout <<"Point PP= "<< pp; 603 Circle c(7,6,5); cout <<"Circle c= "<< c; //radius =7 604 pp = p; cout <<"Point PP= "<< pp; //built in assign = 605 // a circle is a member of the point class so assign a circle to a point. 606 pp = c; //legal; also assignment O.K. 607 cout <<"Point PP= "<< pp; 608 pp= (Point) c; // but better use the cast 609 cout <<"Point PP= "<< pp; //note we get only the point part of the Circle 610 //c = (Circle) pp; // illegal Cannot convert 'class Point' to 'class Circle' 611 //c=pp; //illegal assignment not defined 612 Point* p; 613 p = &c; 614 P->print(); //call base class print 615 ((Circle*)p)->print(); 616 Point& r = c; 617 r.print(); 618 ((Circle&)r).print(); 619 } 620 621 622 类的兼容性规则 623 624 625 #include <iostream.h> 626 class Base 627 { 628 public: 629 void func( ) 630 {cout << "Base class function./n";} 631 }; 632 class Derived : public Base 633 { 634 public: 635 void func( ) 636 {cout << "Derived class function./n";} 637 }; 638 void foo(Base b) 639 { b.func( ); } 640 int main( ) 641 { 642 Derived d; 643 Base b; 644 Base * p = &d; 645 Base& br = d; 646 b = d; 647 b.func( ); 648 d.func( ); 649 p -> func( ); 650 foo(d); 651 br.func( ); 652 return 0; 653 } 654 655 656 657 658 虚析构函数,防止内存泄露 659 660 661 #include <iostream.h> 662 #include <string.h> 663 class Base 664 { 665 protected: 666 int id; 667 char * name; 668 public: 669 // default constructor 670 Base(int a = 0, char * s = "") : id(a) 671 { 672 if (!s) 673 { 674 name = NULL; 675 } 676 else 677 { 678 name = new char[strlen(s) + 1]; 679 strcpy(name, s); 680 } 681 cout << "base default constructor/n"; 682 } 683 // copy constructor 684 Base(const Base& b) : id(b.id) 685 { 686 if (!b.name) { name = NULL; } 687 else 688 { 689 name = new char[strlen(b.name) + 1]; 690 strcpy(name, b.name); 691 } 692 cout << "base copy constructor/n"; 693 } 694 // destructor 695 ~Base( ) 696 { 697 if( name != NULL ) delete [ ] name; 698 cout << "base destructor/n"; 699 } 700 const Base& operator= (const Base& b); 701 friend ostream& operator << (ostream&, const Base&); 702 }; 703 const Base& Base:perator= (const Base& b) 704 { 705 if (this != &b) // Check if an object is assigned to itself. 706 { 707 id = b.id; 708 delete [ ] name; // Destroy the old object. 709 if (!b.name) { name = NULL; } 710 else 711 { 712 name = new char[strlen(b.name) + 1]; 713 strcpy(name, b.name); 714 } 715 } 716 cout << "base assignment operator/n"; 717 return *this; 718 } 719 ostream& operator << (ostream& out, const Base& b) 720 { 721 out << "Base member id = " << b.id << endl; 722 out << "Base member name = " << b.name << endl; 723 724 return out; 725 } 726 class Derived : public Base 727 { 728 private: 729 float f; 730 char * label; 731 public: 732 // default constructor 733 Derived(int a = 0, char * s = "", float x = 0, char * t = "") : Base(a, s), f(x) 734 { 735 if (!t) { label = NULL; } 736 else 737 { 738 label = new char [strlen(t) + 1]; 739 strcpy(label, t); 740 } 741 cout << "derived default constructor/n"; 742 } 743 // copy constructor 744 Derived(const Derived& d) : Base(d), f(d.f) 745 // d used as an instance of Base 746 { 747 if(!d.label) { label = NULL; } 748 else 749 { 750 label = new char [strlen(d.label) + 1]; 751 strcpy(label, d.label); 752 } 753 cout << "derived copy constructor/n"; 754 } 755 // destructor 756 ~Derived( ) 757 { 758 delete [ ] label; 759 cout << "derived destructor/n"; 760 } 761 const Derived& operator= (const Derived& d); 762 friend ostream& operator << (ostream&, const Derived&); 763 }; 764 const Derived& Derived:perator= (const Derived& d) 765 { 766 if (this != &d) 767 { 768 delete [ ] label; 769 Base:perator=(d); // Assign the Base part of d to the Base 770 // part of the object that calls this operator; 771 f = d.f; 772 if (!d.label) { label = NULL; } 773 else 774 { 775 label = new char [strlen(d.label) + 1]; 776 strcpy(label, d.label); 777 } 778 cout << "derived assignment operator/n"; 779 } 780 return *this; 781 } 782 ostream& operator << (ostream& out, const Derived& d) 783 { 784 out << (Base)d; // Convert d to Base object to output Base members. 785 out << "Derived member f = " << d.f << endl; 786 out << "Derived member label = " << d.label << endl; 787 return out; 788 } 789 int main( ) 790 { 791 Derived d1; 792 Derived d2(d1); 793 return 0; 794 }
http://blog.csdn.net/zhaori/article/details/1700356