文章目录
继承简介
继承(inheritance)是C++的三大特性之一,继承机制是面向对象程序设计使代码可以复用的最重要的手段,它允许程序员在保持原有类特性的基础上进行扩展,增加功能。这样定义的新的数据类型不仅拥有新定义的成员,而且还同时拥有旧的成员。
我们称已存在的用来派生新类的类为基类
,又称为父类
。由已存在的类派生出的新类称为派生类
,又称为子类
。继承呈现了面向对象程序设计的层次结构,体现了由简单到复杂的认知过程。以前我们接触的复用都是函数复用,继承是类设计层次的复用。
继承的定义
本文所有测试环境均为:VS2017
//基类
class Base
{
public:
int _b;
};
//派生类
class Derived : public Base
{
public:
int _d;
};
int main()
{
Derived derived;
derived._b = 3;
derived._d = 5;
cout << "derived._b = " << derived._b << " derived._d = " << derived._d << endl;
return 0;
}
运行结果:
内存分布
我们可以看到,在新定义的Derive
类中不仅有它自己的成员变量_d
,也有Base
类中的成员变量_b
,这就是继承。
继承的定义格式
在上面的代码中,我们可以看到在定义Derived
类时,在类的后面多了: public Base
几个字符,这个就是继承的定义方式,我们可以总结如下:
因此,在上面的代码中 Base
类是基类, Derived
类是派生类,继承方式为公有继承。那什么又是继承方式呢?
继承的方式
我们知道,类的访问限定符分为三种,分别为:public
private
protected
。不同的的访问限定符,标志着你能不能访问类的数据成员。继承方式与它相似,也分为三种,分别为:public
private
protected
。不同之处在于,继承方式可以理解为,派生类在继承基类的过程中,对得到的基类中的数据成员做怎样的处理。也就是要对得到的基类中的数据成员再加一层怎样的访问限定符。具体的处理方式,我们可以从下面的几组例子来总结:
//首先,我们先定义一个基类 Base
class Base
{
public:
int _pubb;
protected:
int _prob;
private:
int _prib;
};
我们再以三种不同的继承方式分别继承基类,并且通过分别在派生类的类中和类外访问基类的成员来研究它们:
public继承
class Derived : public Base
{
public:
void test()
{
_pubb = 1;
_prob = 2;
_prib = 3;
}
public:
int _pubd;
protected:
int _prod;
private:
int _prid;
};
运行结果:
我们可以看到,在编译时,编译器提醒基类Base
中的私有成员在被继承后,不能在派生类中被访问。
我们再在类外测试:
int main()
{
Derived derived;
derived._pubb = 1;
derived._prob = 2;
derived._prib = 3;
return 0;
}
运行结果:
编译器提示,
_prob
是保护成员,无法在类外访问。_prib
就更不用说了,在类中都无法访问,在类外就更不行了。而_pubb
没有提示错误。
我们可以得出结论:public
继承(公有继承)方式继承后,基类中各成员的访问权限没有发生变化,依旧保持着原来的访问权限,基类中的私有成员,在派生类中不可见(这里说的不可见是说不能访问)。注意,是在派生类中不可见,而不是不继承。
运行结果:
这里我们可以看到,派生类确实继承到了基类中的私有成员,只是不可见(无法访问)。
protected继承
class Derived : protected Base
{
public:
void test()
{
_pubb = 1;
_prob = 2;
_prib = 3;
}
public:
int _pubd;
protected:
int _prod;
private:d
int _prid;
};
运行结果:
在保护继承时,基类中的私有成员依旧不能在派生类中访问。
我们再在类外进行测试:
int main()
{
Derived derived;
derived._pubb = 1;
derived._prob = 2;
derived._prib = 3;
return 0;
}
运行结果:
编译器提示,_pubb
是保护成员,无法在类外访问。_prob
是保护成员,无法在类外访问。_prib
是原来的错误,在派生类中不可见。
我们可以得出结论:protected
继承(保护继承)方式继承后,基类中public
成员的访问权限变为protected
。基类中protected
成员的访问权限不变。基类中的私有成员,在派生类中不可见。
有人可能会说,上面提示的_pubb没有说是保护的,只是访问错误,那会不会访问权限变为了private
呢,我们可以对Derived
类再派生一次,这次我们采用public
的继承方式,我们直接在新的派生类中进行访问,如果它能访问,则说明是保护的。如果在新派生的类中直接不可见(也就是不可访问),那么_pubb
在进行了protected
继承后,就