首先,为什么c++需要继承,理解继承到底是什么意思?继承分为哪三种继承方式?
为什么需要继承?
在编写大型程序时,往往有很多的类,每个类都有自己的数据成员和函数,但有些类之间的数据成员和函数却相同,为了节省代码量和工作时间,只需继承父类中的数据成员和函数即可。
继承就像是如基类为人,派生类为士兵、工人。基类人有很多特性,如名字、年龄。派生类继承了基类中的特性,派生类士兵、工人,同样也有名字、年龄和其他标识。
继承分为public 公有继承、protected 保护继承、provated私有继承。
public 公有继承
//基类 person
class person
{
public:
person();
~person();
void eat();
int grade;
protected:
int age;
private:
string name;
};
//派生类 work
class work :public person
{
public:
work();
~work();
void m_work();
void show();
private:
double m_salary;
};
派生类work以公有继承方式继承基类Person,基类中person的公有数据成员和函数,被work类继承,自动加载到work类中的公有数据成员和函数中,在work类中表现仍为公有public形式。
即:此work类中公有数据成员和函数为:
public:
void m_work();
void show();
void eat(); //基类继承
int grade; //基类继承
派生类work可以直接访问从基类中派生的数据成员和函数:
work work1;
work1.grade = 3;
work1.eat();
protected 保护继承
class work :protected person
派生类work以protected 保护继承方式继承基类person,被继承过来的数据成员和函数的特性表现为protected的,(基类中的公有数据成员和函数,以及保护类型的数据成员和函数被隐式的放在了派生类中的保护类型成员列中)在派生类work中不可直接访问。
即:此work类中数据成员和函数表现为protected:
protected:
void m_work();
void show();
void eat(); //基类继承
int grade; //基类继承
int age;
provated私有继承
class work :provated person
派生类work以provated 保护继承方式继承基类person,被继承过来的数据成员和函数的特性表现为provated的,基类中的公有数据成员和函数、保护类型的数据成员和函数和私有的数据成员和函数被隐式的放在了派生类中的保护类型成员列中)在派生类work中不可直接访问。
provated:
void m_work();
void show();
void eat(); //基类继承
int grade; //基类继承
int age;
string name;
double m_salary;
所谓是继承中的隐藏是基类和派生类中同名的数据成员和函数如何被访问的,若在派生类中有和基类同名的数据成员和函数,派生类对象访问时访问本派生类中的数据成员和函数,虽然是继承了基类中的同名的数据成员和函数,但会隐式的将其隐藏,若想访问基类中同名的数据成员和函数,可通过基类访问运算符调用即可。
如:
class person
{
public:
person();
~person();
void eat();
int grade;
protected:
int age;
private:
string name;
};
//派生类 work
class work :public person
{
public:
work();
~work();
void m_work();
void eat(); //与基类中的成员函数重名
void show();
int grade; //与基类中的成员重名
private:
double m_salary;
};
int main()
{
work work1;
work1.eat(); //因为基类和派生类中都有此同名函数,但派生类对象访问的是本work类中的函数
work1.person::eat(); //若访问基类中同名函数,则需加上类访问运算符
work1.grade = 3;
work1.person::grade = 8; //同理
return 0;
}
注意:
理解继承的含义,派生类的对象是可以给基类中对象赋值,但反过来不行,因为派生类中的对象是属于基类中的一部分,属于包含关系。基类中的对象可以访问派生类中的对象,如指针和引用。
person &p1 = soldier s;
persom *p2 = soldier s;
person p3 = soldier s;
class soldier;
person *p = new soldier;
p-> soldier.name;
delete p; //会调用析构函数,将基类中内存释放,但子类中对象内存不会被释放,则会造成内存泄漏,则选用的方法是用虚析构函数,则可以两者全部析构。
p = NULL;
虚析构函数
什么时候用到析构函数呢,就是存在继承关系,想用父类指针去指向堆中的子类对象,并且想使用父类指针去释放这块内存,则选用虚析构函数。