介绍
- 继承的基本概念
1.共性和个性 (PS:有相同的属性 但是 又有自己的特点)- 基类和子类
1. 基类(父类) = 共性
2. 子类(派生类) = 个性(特点)- 继承语法
1.class 子类名:继承方式1 基类1,继承方式2 基类2{ 行为 };
- 继承方式(PS:默认继承方式为:私有继承)
1.公有继承: public
2.保护继承: protected
(PS:在子类中可以看到,子类可以访问)
3.私有继承: private
(PS:在子类中可以看到,但是无法访问)- 继承的使用场景
1.创建的新类与现有的类相似,只是多出若干成员变量或成员函数时,可以使用继承。不但减少代码量,而且新类会拥有基类所有功能
2.需要创建多个类,它们拥有很多相似的成员变量或成员函数时,可以使用继承。将这些类的共同成员提取出来,定义为基类,然后从基类继承,既可以代码复用,也方便后期维护- 继承注意事项
1.在子类中定义基类同名的 公有成员和保护成员,子类中的成员会 隐藏 基类中的 同名成员,想访问被隐藏的成员,通过作用域限定符(::)+成员名 可以访问 被隐藏的基类成员
2.在基类中构造函数设置为私有成员的化,子类无法进行继承
3.子类初始化 基类成员变量 或者 函数需要显示构造2.1基类成员初始化方法一:
Student(string name, int age = 0, string gender = "男"):Person(name, age, gender){}//三参构造(PS:需要 基类有三参构造函数)
2.2基类成员初始化方法二:Student(string name, int age = 0, string gender = "男"){m_name = name;m_gender = gender;oage(age);}//无参构造(PS:需要 基类有默认无参构造函数)
公有继承特点
1.子类可以 直接访问 基类所有的 公有和保护成员,其效果如同它们是在子类中声明一样
2.对于基类的 私有成员,在子类中存在 但无法访问
3.子类对象 任何时候都可以被当成 基类对象
保护继承特点
1.使基类 公有成员 和 保护成员 进行保护化,只禁止外部通过该子类访问
2.子类指针 或 引用 不能隐式转换成基类类型 指针或引用
私有继承特点
1.将基类公有和保护成员私有化,禁止外部通过该子类访问,也禁止该子类的子类进行访问
2.子类指针 或 引用 不能隐式转换成基类类型 指针或引用
继承方式与访问控制
公有继承 保护继承 私有继承区别源码
#include<iostream>
#include<string>
using namespace std;
//基类A
class A
{
public:
int m_pub;//公有成员变量
protected:
int m_pro;//保护成员变量
private:
int m_pri;//私有成员变量
};
//子类B
class B:protected A//保护继承基类,在全局中是无法通过 子类去访问基类(包括子类的子类也无法访问)
{
public:
void foo()
{
cout << m_pub << " " << m_pro << endl;
}
};
//子类C
class C :private B//私有继承,无法访问任何成员
{
public:
//B::foo();//无法访问B类中成员函数
};
void main()
{
A a;
a.m_pub = 10;
B b;
//b.m_pub;//可以看见,但是无法访问
system("pause");
}
子类内存布局
子类对象内存布局图:
源码
#include<iostream>
#include<string>
using namespace std;
class A
{
public:
A(){
cout << "A构造" << endl; }
~A(){
cout << "A析构" << endl; }
};
class Person:public A//人
{
public:
//默认构造函数
Person(){
cout << "Person构造" << endl; }
//构造函数
Person(string name, int age, string gender) :m_name(name), m_age(age), m_gender(gender){
}
//析构函数
~Person(){
cout << "Person析构" << endl; }
public:
void eat(){
cout << "吃饭" << endl; }
void sleep(){
cout << "睡觉" << endl; }
//打印函数
void print()
{
cout << m_name << " " << m_age << " " << m_gender << endl;
}
//获取年龄
int oage(int age)
{
return m_age = age;
}
protected:
string m_name;//名字
string m_gender;//性别
private:
int m_age;//年龄
};
//子类 学生
class Student:public Person//人
{
public:
//构造函数
Student(string name, int age = 0, string gender = "男")/*:Person(name, age, gender)//三参构造*/
{
cout << "Student构造" << endl;
//基类成员初始化方法二
m_name = name;
m_gender = gender;
oage(age);
}
//打印
void study()
{
eat();
cout << "学习" << endl;
m_name = "一航";
}
~Student()
{
cout << "Student析构" << endl;
}
};
void main()
{
//构造 and 析构流程测试
{
//构造子类对象
Student stu("一航");
cout << "--------------分隔符--------------" << endl;
//函数调用
stu.study();
cout <<"--------------分隔符--------------"<< endl;
//拷贝子类对象操作
Person*Ph1 = &stu;
Person&Ph2 = stu;
//打印结果
Ph1->print();
Ph2.print();
cout << "--------------分隔符--------------" << endl;
}
system("pause");
}
运行结果
A构造
Person构造
Student构造
--------------分隔符--------------
吃饭
学习
--------------分隔符--------------
一航 0 男
一航 0 男
--------------分隔符--------------
Student析构
Person析构
A析构
请按任意键继续. . .