一、类的继承
1.派生类 :
声明派生类的一般形式为:
class 派生类名:[ 继承方式 ] 基类名
{
派生类新增加的成员
};
#include<iostream>
#include <string>
using namespace std;
class Student
{
public:
void display()
{
cout << "num:" << num << endl;
cout << "name:" << name << endl;
cout << "num:" << num << endl;
}
private:
int num;
string name;
char sex;
};
class Student1 : public Student // 声明基类是Student【:后面要有空格!】
{
public:
void display_1() // 新增加的成员函数
{
display();//=============继承display()函数【这样就连着display函数里的一块输出了】
cout << "age:" << age << endl;
cout << "address:" << addr << endl;
}
private:
int age; // 新增加的数据成员
string addr; // 新增加的数据成员
};
int main()
{
Student1 stud;
stud.display_1();
return 0;
}
继承类型
构造与析构问题
像栈一样
多重继承的二义性
使用基类名限定(比如c1.A::a=3;)
类的组合
继承是纵向的,组合是横向的
基类与派生类的组合
2.虚基类virtual
使得在继承间接共同基类时只保留一份成员。
virtual [继承方式] 基类名
做了虚基类声明后,派生类D的成员如下:
将类A声明为虚基类的方法如下:
class A // 声明基类A
{……};
class B:virtual public A
// 声明类B是类A的公用派生类,A是B的虚基类
{……};
class C:virtual public A
// 声明类C是类A的公用派生类,A是C的虚基类
{……};
二、虚函数
多态性是指发出同样的消息,不同类型的对象 接收时会产生不同的行为。
允许在派生类中重新定义与基类同名的函数, 并且可以通过基类指针或引用来访问基类和派生 类中的同名函数。
由虚函数实现的动态多态性就是: 同一类族中不同类的对象,对同一 函数调用作出不同反应。
1.虚函数对同一消息,不同对象有 不同的响应方式。
#include <iostream>
#include <string>
using namespace std;
//声明基类Student
class Student
{
public:
Student(int, string, float); //声明构造函数
virtual void display();//声明输出函数【*】注意此处virtual===========================
protected: //受保护成员,派生类可以访问
int num;
string name;
float score;
};
//Student类成员函数的实现
Student::Student(int n, string nam, float s)//定义构造函数
{
num = n;
name = nam;
score = s;
}
void Student::display()//定义输出函数
{
cout << "num:" << num << "\nname:" << name << "\nscore:" << score << "\n\n";
}
//声明公用派生类Graduate
class Graduate :public Student
{
public:
Graduate(int, string, float, float);//声明构造函数
void display();//声明输出函数
private:float pay;
};
// Graduate类成员函数的实现
void Graduate::display()//定义输出函数
{
cout << "num:" << num << "\nname:" << name << "\nscore:" << score << "\npay=" << pay << endl;
}
Graduate::Graduate(int n, string nam, float s, float p) :Student(n, nam, s), pay(p) {}
//主函数
int main()
{
Student stud1(1001, "Li", 87.5);//定义Student类对象stud1
Graduate grad1(2001, "Wang", 98.5, 563.5);//定义Graduate类对象grad1
Student *pt = &stud1;//定义指向基类对象的指针变量pt
pt->display();
pt = &grad1;
pt->display();
return 0;
}
以下摘自 谭浩强《c++面向对象程序设计》第207页
到不同的目的地要乘坐指定的不同的公交车,一一 对应,不能搞错。如果能够用同一种方式去调用同一类族中不同类的所有的同名函数,那就好了。
用虚函数就能顺利地解决这个问题。下面对程序作一点修改,在Student类中声明display函数时,在最左面加一个关键字virtual……看!这就是虚函数的奇妙作用。现在用同一个指针变量(指向基类对象的指针变量),不但输出了学生stud1的全部数据,而且还输出了研究生grad1的全部数据,说明已调用了grad1的display函数。用同一种调用形式“pt->display()”,而且pt是同一个基类指针,可以调用同一类族中不同类的虚函数。这就是多态性,对同一消息,不同对象有 不同的响应方式。
说明:本来基类指针是用来指向基类对象的,如果用它指向派生类对象,则进行指针类型转换,将派生类对象的指针先转换为基类的指针,所以基类指针指向的是派生类对象中的基类部分。在程序修改前,是无法通过基类指针去调用派生类对象中的成员函数的。虚函数突破了这一限制,在派生类的基类部分中,派生类的虚函数取代了基类原来的虚函数,因此在使基类指针指向派生类对象后,调用虚函数时就调用了派生类的虚函数。 要注意的是,只有用virtual声明了虚函数后才具有以上作用。如果不声明为虚函数,企图通过基类指针调用派生类的非虚函数是不行的。
2.纯虚函数与抽象类
纯虚函数
纯粹为了用来继承的,只留下一个函数名
比如:
virtual void fun()
虚函数,派生类继承时可以不重写该函数
virtual void fun()=0
纯虚函数,这种函数在派生类中必须重写,否则该派生来也是个虚基类,而虚基类是不能定义对象的
前者是定义一个虚函数,后者是定义一个纯虚函数,可以理解为接口。虚函数在C++里的作用是为了配合多态使用,也就是说,基类的指针指向派生类的对象时,我们调用的这个虚函数,实际上是当前实际的派生类对象响应(如果派生类实现了该方法)这个过程推荐看下关于面向对象的一大特性多态。
抽象类
只作为基本类型用来继承的类
虚函数详解:C语言中文网:http://c.biancheng.net/cpp/biancheng/view/244.html