类的继承
简单介绍
C++是一种面向对象的语言,最重要的一个目的就是——提供可重用的代码,而类继承就是C++提供来扩展和修改类的方法。类继承就是从已有的类中派生出新的类,派生类继承了基类的特性,同时可以添加自己的特性。实际上,类与类之间的关系分为三种:代理、组合和继承。以下是三种关系的图解:(为了更好的理解)

基类可以派生出派生类,基类也叫做“父类”,派生类也称为“子类”。
那么,派生类从基类中继承了哪些东西呢?分为两个方面:1. 变量——派生类继承了基类中所有的成员变量,并从基类中继承了基类作用域,即使子类中的变量和父类中的同名,有了作用域,两者也不冲突。2.方法——派生类继承了基类中除去构造函数、析构函数以外的所有方法。子类除了具有基类的所有成员(包括成员变量和成员函数)之外,还可以添加自己特有的成员(包括变量和函数)
继承方式和访问限定符
继承方式:public, protected, private
结构类型struct默认是public继承
类类型class默认是private继承

总的来说,父类成员的访问限定符通过继承派生到子类中之后,访问限定符的权限小于、等于原权限。其中,父类中的private成员只有父类本身及其友元可以访问,通过其他方式都不能进行访问,当然就包括继承。protected多用于继承当中,如果对父类成员的要求是——子类可访问而外部不可访问,则可以选择protected继承方式。
虽然有的成员变量无法访问,但都继承下来了,也占空间。
派生类对象的构造方式
前面也提到,派生类将基类中除去构造函数和析构函数的其他方法继承了过来,那么对于派生类对象中自己的成员变量和来自基类的成员变量,它们的构造方式是怎样的呢?
答案是:在定义子类对象时, 先自动调用基类的构造函数,然后再自动调用子类本身的构造函数 (正序构造)。在释放子类对象时, 先自动调用子类本身的析构函数,然后再自动调用基类的析构函数(逆序析构)符合栈的结构特点
如下展示:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34
| #include<iostream> using namespace std;
class Shape { public: Shape() { cout<<"Shape()"<<endl; } ~Shape() { cout<<"~Shape()"<<endl; } };
class Rectangle:public Shape { public: Rectangle() { cout<<"Rectangle:public Shape"<<endl; } ~Rectangle() { cout<<"~Rectangle:public Shape"<<endl; } };
int main() { Rectangle r; return 0; }
|
结果
1 2 3 4
| Shape() Rectangle:public Shape ~Rectangle:public Shape ~Shape()
|
类的多态
多态:在具有继承关系的多个对象中,通过基类指针(或基类引用)来调用不同子类中的同名成员函数,自动(当然也可以手动,例如cout<<a.rectangle::area()<<'\n'<<a.area();
,其中a是用rectangle的子类创建的对象)根据不同子类的类型,来实现不同的功能(呈现不同的形态)
通常使用虚函数(virtual)来实现多态
例子:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73
| #include<iostream> using namespace std;
class Shape { private: double s; double c; public: void setArea(double ss); virtual double getArea(); void setCircumference(double cc); double getCircumference(); };
class Rectangle:public Shape { private: double length; double width; public: void setLength(double len); void setWidth(double wid); virtual double getArea(); };
int main() { Rectangle rect; double len,wid; cout<<"Enter length and width:"; cin>>len>>wid; rect.setLength(len); rect.setWidth(wid); cout<<rect.getArea();
return 0; }
void Shape::setArea(double ss) { s=ss; }
double Shape::getArea() { return s; }
void Shape::setCircumference(double cc) { c=cc; }
double Shape::getCircumference() { return c; }
void Rectangle::setLength(double len) { length=len; }
void Rectangle::setWidth(double wid) { width=wid; } double Rectangle::getArea() { return length*width; }
|
补充:类中指针的巧妙运用
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75
| #include<iostream> using namespace std; class Shape { public: virtual void draw() { cout<<"Shape"<<endl; } };
class Circle:public Shape { public : virtual void draw() { cout<<"Circle"<<endl; } };
class Rectangle:public Shape { public: virtual void draw() { cout<<"Rectangle"<<endl; } };
void drawShape1(Shape *x) { x->draw(); }
void drawShape2(Shape &x) { x.draw(); }
int main() { Shape s; Circle c; Rectangle r; cout << "-------------------------" << endl; Shape *pShape; pShape = &s; pShape->draw(); pShape = &c; pShape->draw(); pShape = &r; pShape->draw(); cout << "-------------------------" << endl; drawShape1(&s); drawShape1(&c); drawShape1(&r); cout << "-------------------------" << endl; drawShape2(s); drawShape2(c); drawShape2(r); cout << "-------------------------" << endl; return 0; }
|
指针也可以用来创建子类对象
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60
| #include <iostream> using namespace std;
class BaseCalculator { public: int m_A; int m_B; virtual int getResult() { return 0; } };
class AddCalculator : public BaseCalculator { public: virtual int getResult() { return m_A+m_B; } };
class SubCalculator : public BaseCalculator { public: virtual int getResult() { return m_A-m_B; } };
int main() {
BaseCalculator* cal = new AddCalculator; cal->m_A = 10; cal->m_B = 20; cout << cal->getResult() << endl; delete cal;
cal = new SubCalculator; cal->m_A = 20; cal->m_B = 10; cout << cal->getResult() << endl; delete cal; return 0; }
|