本文章是看C++Primer这本书及网上查的资料对C++继承做了一个简单的总结:
OOP(Object-oriented pragramming)面向对象程序设计的核心思想是:数据抽象,继承和动态绑定。
通过使用数据抽象可以将类的接口与实现分离,利用继承可以定义相似类型的关系的建模。通过动态绑定,可以一定程度上忽略相似类型的区别,而以统一方式使用它们的对象。
继承:通过继承联系在一起的类构成一种层次关系。将被继承的类称为基类继承的类将派生类。
继承提高代码的重复利用率,体现类的共性与个性。
继承的语法:
class 类名1 :[继承方式] 类名2,类名3,类名4
{
}
类名2,类名3,类名4 被继承的类称为父类(基类)
类名1:子类(派生类)
C++继承分:
公有继承(public)、私有继承(private)、保护继承(protected)三种继承方式。
在C++语言中,一个派生类可以从一个基类派生,也可以从多个基类派生。从一个基类派生的继承称为单继承;从多个基类派生的继承称为多继承。
根据继承方式决定子类是否能访问父类的成员。
1. 公有继承(public)
公有继承的特点是基类的公有成员和保护成员作为派生类的成员时,它们都保持原有的状态,而基类的私有成员仍然是私有的,不能被这个派生类的子类所访问。
2. 私有继承(private)
私有继承的特点是基类的公有成员和保护成员都作为派生类的私有成员,并且不能被这个派生类的子类所访问。
3. 保护继承(protected)
保护继承的特点是基类的所有公有成员和保护成员都成为派生类的保护成员,并且只能被它的派生类成员函数或友元访问,基类的私有成员仍然是私有的。
对应表派生类的内存大小,无论是哪种方式继承,派生类都会为基类分配内存空间,此时要计算派生类的大小应考虑内存对齐。
派生类与基类构造顺序:
先构造基类,再构造派生类
先析构派生类,再析构基类
赋值兼容:
a.派生类对象可以赋值给基类对象
b.基类指针可以指向派生类对象
c.基类的引用可以引用派生类对象
只能把派生类对象赋值给基类的对象或指针,引用,不能把基类赋值给派生类
覆盖:基类与派生类之间方法关系:
a.派生类存在与基类完全一样的非虚方法(没有virtual修饰的方法也叫实方法)(方法 参数列表一样)
b.派生类存在与基类方法名一样,参数列表不一样
重载:在同一个类中方法名一样,参数列表不一样
重载和覆盖的区别:
1.重载在同一类中,覆盖在多个类中
2.重载时函数名一样,参数列表不一样
一个派生类继承多个基类:基类构造顺序与继承顺序有关
基类存在相同方法(方法名一样),调用时通过基类限制
/*
一个派生类继承多个基类
*/
class base1
{
public:
base1(int a)
{
cout<<"base1 constructor"<<endl;
}
void fun()
{
cout<<"base1 fun"<<endl;
}
};
class base2
{
public:
base2(int b)
{
cout<<"base2 constructor"<<endl;
}
void fun(int a)
{
cout<<"base2 fun"<<endl;
}
};
//基类构造顺序与继承顺序有关
class child:public base2,public base1
{
public:
child():base1(1),base2(2)
{
}
};
int main(int argc, char const *argv[])
{
/*当派生类与基类方法完全一样时,只有直接通过派生类对象调用方法才是派生类的,不管是基类对象 基类指针 基类引用都是基类的方法*/
Child c1(12,123);
c1.fun();//派生类方法
Base b=c1;//只能把派生类对象赋值给基类的对象或指针,引用。不能把基类赋值给派生类
b.fun();//基类的方法
Base* b1=&c1;
b1->fun();//基类的方法
Base &b2=c1;
b2.fun();//基类的方法
/*当派生类没有方法是,通过派生类调用的方法是基类的,当有多个基类时且基类都有相同名字的方法,需要通过基类控制。*/
child c1;
//c1.fun();//报错。fun产生歧义
c1.base1::fun();
c1.base2::fun(21);
return 0;
}