学习之路:C++中的继承

  1. 继承的概念
    继承是使得面向对象程序设计使代码可以复用的主要手段,可以在保持原有类的基础上进行扩展,这样产生的类叫派生类,也叫子类,原来的类叫基类也叫父类,继承是类设计层次的复用。
    语法格式为
class person //基类
{
public:
........
	protected:
	string _name = "C++";
	int _age = 35;
};


class student :public person//student 为派生类
{....
}

语法为class/struct + 派生类名字+:+继承方式+基类名字
继承方式有三类 private,public,protected
如果继承方式不写,class默认为private继承,struct默认为public继承。

继承规则遵循同小取小,基类的private在public中不开见。
例如假如是protected继承,则基类的public的成员在派生类中被视为protected成员,如果是public继承,则基类的private不可见,其他的成员访问权限不会变化。
总结

  1. 基类的private成员在派生类中是不可见的,不可见指基类的私有成员被继承到派生类对象中,但语法限制派生类对象不管是类里面,还是类外面都不能访问。
  2. 在实际的运用中一般是public继承,很少用protected/private,因为实际中扩展维护性不强。

2.基类和派生类对象赋值转换

派生类对象可以赋值给基类的对象/指针/引用,叫做切片或切割,意思是把派生类的那部分切过去赋值。例如

class person 
{
public:
	person(const string &name = "C++", const int &age = 35)
	{
		_name = name;
		_age = age;
	}
	void print()
	{
		cout << _name<< endl;
		cout << _age << endl;
	}

protected:
	string _name = "C++";
	int _age = 35;
};//基类

class student :public person
{
public:
	student(int stuid=123456) :person("java", 23)
	{
		_stuid = stuid;
	}
	void print()
	{
		cout << _name << endl;
		cout << _age << endl;
		cout << _stuid << endl;
	}

	void ccc()
	{
		cout << _stuid;
	}
	int _stuid = 23;
protected:
	

};//派生类

void test1()
{
	person m;
	
	student n;
	n.print();
	m = n;
	m.print();
	person *dd1 = &n;
	dd1->print();
	person &dd2 = n;
	dd2.print();
}

可以想象如下图
在这里插入图片描述
相当于只给基类需要的属性,将不需要的切掉了。
如果想把基类的赋值给子类,需要通过强制类型限制赋值给指针或者引用(底层的实现还是指针),


void test2()
{
	person mm;
	person *msl = &mm;
	student nn;

	student *nsl = (student*)&mm;//可能有越界访问的问题

	nsl->print();

}

3.继承中的作用域

  1. 在继承体系中基类和派生类有独立的作用域
  2. 子类和父类中有同名成员,子类成员将屏蔽父类对同名成员的直接访问,这种情况叫隐藏,也叫重定义,可以类比局部变量覆盖了全局变量。
  3. 要注意成员函数,函数名相同就能构成隐藏
  4. 尽量避免继承体系中定义同名的成员
    例如上面的person和student的print成员函数实际上已经构成了隐藏。

4.派生类的默认成员函数

在C++中我们知道默认函数有四个分别为构造函数,拷贝构造函数,赋值函数,析构函数。
在继承体系下的默认成员函数有以下结几个特点

  1. 派生类的构造函数必须调用基类的构造函数初始化基类的那一部分成员。如果基类没有默认的构造函数,则必须在派生类的构造函数的初始化列表阶段显示调用
  2. 派生类的拷贝构造函数必须调用基类的拷贝构造函数完成基类的拷贝构造
  3. 同理operator=也要调用基类的operator=
  4. 派生类的析构函数会自动调用基类的析构函数清理基类成员,如果显式调用反而会出错。
  5. 派生类对象初始化先调用基类构造在调用派生类
  6. 派生类对象析构先调用派生类析构再调用基类析构,调用顺序和栈的思想有些类似。

5继承与友元

友元关系不能继承,也就是说基类友元不能访问子类私有和保护成员,同时基类的private成员在派生类中不可见,所以派生类的友元也不能访问基类的private成员

6继承与静态成员

基类定义了static静态成员,则整个继承体系里面只有一个静态成员,C++static属于所有的对象

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值