数字展厅网站建设,网站续费贵是重新做个好还是续费,查企业法人电话大全,微信小商店怎么推广⭐上篇模板文章#xff1a;24. C模板 2 (非类型模板参数#xff0c;模板的特化与模板的分离编译)-CSDN博客 ⭐本篇代码#xff1a;c学习 橘子真甜/c-learning-of-yzc - 码云 - 开源中国 (gitee.com) ⭐标⭐是比较重要的部分 目录 一. 继承的基础使用
1.1 继承的格式
1.2 … ⭐上篇模板文章24. C模板 2 (非类型模板参数模板的特化与模板的分离编译)-CSDN博客 ⭐本篇代码c学习 · 橘子真甜/c-learning-of-yzc - 码云 - 开源中国 (gitee.com) ⭐标⭐是比较重要的部分 目录 一. 继承的基础使用
1.1 继承的格式
1.2 代码举例
1.3 派生类访问基类成员的变化⭐
二. 继承的复制兼容规则 ⭐ 三. 继承中的作用域
3.1 基类可以访问父类成员函数
3.2 基类与派生类的重定义 一. 继承的基础使用 继承的面向对象程序设计提高代码复用的重要手段它允许我们在保持原有类的成员的基础上对这个类进行拓展。之前我们大多都是函数的复用继承是类的复用。 被继承的类称为基类父类继承基类的类称为派生类子类。 比如我们有一个person类而学生职工教师等类都有着person类的属性年龄性别电话身份证等而学生有自己特有的学号教师职工有自己的工号。 此时我们就能通过继承让学生教师职工类获取person的成员还能重新定义自己特有的成员。
1.1 继承的格式
class Person
{};class Student :public Person
{};
在新定义的类后面使用一个 : 后面依次接 继承方式 基类 1.2 代码举例
#include iostream
using namespace std;class Person
{
public:Person(int age 18, const string name 张三):_age(age), _name(name){};void print(){cout 姓名: _name 年龄: _age endl;}
private:size_t _age;string _name;
};class Student :public Person
{
private:string _stuid;
};class Teacher :public Person
{
private:string _tcid;
};int main()
{Person p1;p1.print();Student st1;st1.print();Teacher tc1;tc1.print();return 0;
}
上面代码中我们定义一个person类在定义学生和教师类来继承person 。
我们都调用print函数运行结果如下 可见学生类和教师类派生类都能够继承person类基类的姓名年龄和print函数
1.3 派生类访问基类成员的变化⭐ 继承的方式有三种,public,protected,private。不同的继承方式子类访问父类有限定。
类成员/继承方式public继承protected继承private继承基类public成员派生类public成员派生类protected成员派生类private成员基类protected成员派生类protected成员派生类protected成员派生类private成员基类private成员派生类不可访问派生类不可访问派生类不可访问 根据上述表格我们可以有以下总结 1 基类的private成员在派生类中不可见。即这个成员被派生类继承但是在派生类的类内类外都无法访问基类的private成员 2 protected继承就是为了解决基类private成员无法在派生类访问的问题即如果我们想要在派生类访问基类的私有成员在基类中将其定义为protected成员即可 3 实际上为了提高代码的复用和拓展。我们一般都使用public继承 4 class定义类的默认继承方式是privatestruct定义类的默认继承方式是public。不过我们在使用中一般都会显示定义类的继承方式。 若是保护成员在派生类中可以访问
#include iostream
using namespace std;class Person
{
public:Person(int age 18, const string name 张三):_age(age), _name(name){};void print(){cout 姓名: _name 年龄: _age endl;}
protected:size_t _age;string _name;
};class Student :public Person
{
public:void show(){cout 姓名: _name 年龄: _age endl;}
private:string _stuid;
};int main()
{Person p1;p1.print();Student st1;st1.show();return 0;
}
我们在Student类中定义一个show函数来访问基类的保护成员 二. 继承的复制兼容规则 ⭐ 派生类的对象可以赋值给 基类基类的指针基类的引用称为切片切割 基类的对象不能赋值给派生类 基类的指针在特定情况下可以强制转化为派生类的指针 代码举例
#include iostream
using namespace std;class Person
{
public:Person(int age 18, const string name 张三):_age(age), _name(name){};void print(){cout 姓名: _name 年龄: _age endl;}
protected:size_t _age;string _name;
};class Student :public Person
{
public:void set(int age, const string name,int stuid){_age age;_name name;_stuid stuid;}void show(){cout 姓名: _name 年龄: _age ID: _stuid endl;}
private:string _stuid;
};int main()
{Student st1;st1.set(50, 李四, 123456);st1.print();Student st2;Person p1 st1; //直接赋值p1.print();Person* p2 st2; //基类指针p2-print();Person p3 st2; //基类引用p3.print();return 0;
}
运行结果如下 若是将基类赋值给派生类就会报错 三. 继承中的作用域 1 在继承中基类和派生类有自己独立的作用域。对于派生类来说调用成员的时候会现在自己的类中寻找如果自己的类中没有定义再去基类中寻找成员 2 基类和其派生类有相同名称的成员派生类会隐藏基类的成员。这两个成员构成重定义。 3 重定义不是重载。虽然两个成员名称相同但是它两的作用域不一样不是重载 3.1 基类可以访问父类成员函数
举例代码如下基类没有print函数会去父类寻找并调用print函数
#include iostream
using namespace std;class Person
{
public:Person(int age 18, const string name 张三):_age(age), _name(name){};void print(){cout 姓名: _name 年龄: _age endl;}
protected:size_t _age;string _name;
};class Student :public Person
{
private:string _stuid;
};int main()
{Student st1;st1.print();return 0;
}
测试结果如下 3.2 基类与派生类的重定义 如果父子类有重定义子类无法直接调用父类的成员 调用自己的成员
#include iostream
using namespace std;class A
{
public:void f() { cout hello world! endl; }
};class B :public A
{
public:void f(int i) { cout hello world! i endl; }
};int main()
{A a;B b;a.f();b.f(10);return 0;
} 如果父子类构成重定义子类想要访问父类同名成员需要指定作用域