当前位置: 首页 > article >正文

c++-------------------------继承

1.继承的概念和定义

1.1继承的概念

继承(inheritance)机制是⾯向对象程序设计使代码可以复⽤的最重要的⼿段,它允许我们在保持原有 类特性的基础上进⾏扩展,增加⽅法(成员函数)和属性(成员变量),这样产⽣新的类,称派⽣类。继承 呈现了⾯向对象程序设计的层次结构,体现了由简单到复杂的认知过程。以前我们接触的函数层次的 复⽤,继承是类设计层次的复⽤。
1.2继承的定义
我们先来看一下继承的格式
下⾯我们看到Person是基类,也称作⽗类。Student是派⽣类,也称作⼦类。(因为翻译的原因,所以 既叫基类/派⽣类,也叫⽗类/⼦类)
1.2.2   继承基类成员访问⽅式的变化
1. 基类private成员在派⽣类中⽆论以什么⽅式继承都是不可⻅的。这⾥的不可⻅是指基类的私有成员
还是被继承到了派⽣类对象中,但是语法上限制派⽣类对象不管在类⾥⾯还是类外⾯都不能去访问
它。
2. 基类private成员在派⽣类中是不能被访问,如果基类成员不想在类外直接被访问,但需要在派⽣类
中能访问,就定义为protected。可以看出保护成员限定符是因继承才出现的。
3. 实际上⾯的表格我们进⾏⼀下总结会发现,基类的私有成员在派⽣类都是不可⻅。基类的其他成员
在派⽣类的访问⽅式 == Min(成员在基类的访问限定符,继承⽅式),public > protected >
private。
4. 使⽤关键字class时默认的继承⽅式是private,使⽤struct时默认的继承⽅式是public,不过最好显
⽰的写出继承⽅式。
class Person
{
public :
void Print ()
{
cout<<_name <<endl;
}
protected :
string _name ; // 姓名
private :
int _age ; // 年龄
};
//class Student : protected Person
//class Student : private Person
class Student : public Person
{
protected :
int _stunum ; // 学号
};

下面我们来看一下继承类模板
namespace bit
{
//template<class T>
//class vector
//{};
// stack和vector的关系,既符合is-a,也符合has-a
template<class T>
class stack : public std::vector<T>
{
public:
void push(const T& x)
{
// 基类是类模板时,需要指定⼀下类域,
// 否则编译报错:error C3861: “push_back”: 找不到标识符
// 因为stack<int>实例化时,也实例化vector<int>了
// 但是模版是按需实例化,push_back等成员函数未实例化,所以找不到
vector<T>::push_back(x);
//push_back(x);
}
void pop()
{
vector<T>::pop_back();
}
const T& top()
{
return vector<T>::back();
}
bool empty()
{
return vector<T>::empty();
}
};
}
int main()
{
bit::stack<int> st;
st.push(1);
st.push(2);
st.push(3);
while (!st.empty())
{
cout << st.top() << " ";
st.pop();
}
return 0;
}

简单的来说我们继承就是把每个派生类都有的属性放到基类里面然后派生类去进程基类这样就可以避免代码的冗余然后同时也可以获得对应的属性

下面我们再来了解一下继承和友元

友元关系不能继承,也就是说基类友元不能访问派⽣类私有和保护成员
class Student;
class Person
{
public:
friend void Display(const Person& p, const Student& s);
protected:
string _name; // 姓名
};
class Student : public Person
{
protected:
int _stuNum; // 学号
};
void Display(const Person& p, const Student& s)
{
cout << p._name << endl;
cout << s._stuNum << endl;
}
int main()
{
Person p;
Student s;
// 编译报错:error C2248: “Student::_stuNum”: ⽆法访问 protected 成员
// 解决⽅案:Display也变成Student 的友元即可
Display(p, s);
return 0;
}

继承模型

我们来简单的看一下继承的模型

class Person
2 {
3 public:
比特就业课
string _name; // 姓名
};
class Student : public Person
{
protected:
int _num; //学号
};
class Teacher : public Person
{
protected:
int _id; // 职⼯编号
};
class Assistant : public Student, public Teacher
{
protected:
string _majorCourse; // 主修课程
};
int main()
{
// 编译报错:error C2385: 对“_name”的访问不明确
Assistant a;
a._name = "peter";
// 需要显⽰指定访问哪个基类的成员可以解决⼆义性问题,但是数据冗余问题⽆法解决
a.Student::_name = "xxx";
a.Teacher::_name = "yyy";
return 0;
}

虚继承

虚继承我感觉对于c++是有个比较好玩切好用的东西

比如下面代码

class Person
{
public:
string _name; // 姓名
/*int _tel;
int _age;
string _gender;
string _address;*/
// ...
};
// 使⽤虚继承Person类
class Student : virtual public Person
{
protected:
int _num; //学号
};
// 使⽤虚继承Person类
class Teacher : virtual public Person
{
protected:
int _id; // 职⼯编号
};
// 教授助理
class Assistant : public Student, public Teacher
{
protected:
string _majorCourse; // 主修课程
};
int main()
{
// 使⽤虚继承,可以解决数据冗余和⼆义性
Assistant a;
a._name = "peter";
return 0;
}
今天的继承就到这里如果有错误的地方还建议大家多多指出谢谢大家

http://www.kler.cn/a/516019.html

相关文章:

  • 数据缺失补全方法综述
  • 常见的加密方式以及自定义加密工具
  • 【前端】Hexo 部署指南_hexo-deploy-git·GitHub Actions·Git Hooks
  • springboot 调用 c++生成的so库文件
  • springboot基于微信小程序的商城系统
  • 微软Win10 RP 19045.5435(KB5050081)预览版发布!
  • 神经网络梯度爆炸的原因及解决方案
  • 10个非常基础的 Javascript 问题
  • Seata进阶全文详解(集成Nacos及SpringCloud配置)
  • web服务器 网站部署的架构
  • 三格电子新品丨三菱Q系列PLC转网口
  • Kotlin基础知识学习(四)
  • 每日十题八股-2025年1月23日
  • PyQt5之QLabel
  • Spring Security(maven项目) 3.0.2.6版本—总
  • OpenEuler学习笔记(十一):OpenEuler上搭建LAMP环境
  • 速通Docker === 使用最佳实践总结
  • deap系统重构,再新增一个新的因子,年化39.1%,卡玛提升至2.76(附python代码)
  • 嵌入式知识点总结 ARM体系与架构 专题提升(三)-中断与异常
  • 字节跳动自研HTTP开源框架Hertz简介附使用示例
  • 人工智能如何重塑音频、视觉及多模态领域的应用格局
  • 詳細講一下在RN(ReactNative)中,6個比較常用的組件以及詳細的用法
  • can not be imported as a dangling index
  • 低代码平台放入外部链接有缓存不生效
  • 【全栈】SprintBoot+vue3迷你商城-扩展:vue的基本用法
  • springboot 调用 c++生成的so库文件