首页 > 编程语言 >c++继承特点,菱形继承,访问方式,默认成员函数

c++继承特点,菱形继承,访问方式,默认成员函数

时间:2024-07-13 19:29:49浏览次数:25  
标签:name 继承 成员 c++ class Person 菱形 public

目录

继承概念

继承特性

继承后成员访问的方式的变化

子父类成员重命名

派生类的默认成员函数

​编辑

菱形继承

小tip


继承概念

继承(inheritance)机制是面向对象程序设计使代码可以复用的最重要的手段,它允许程序员在保
持原有类特性的基础上进行扩展,增加功能,这样产生新的类,称派生类。继承呈现了面向对象
程序设计的层次结构,体现了由简单到复杂的认知过程。以前我们接触的复用都是函数复用,继
承是类设计层次的复用。

格式

继承特性

继承后成员访问的方式的变化

tip:
1.使用关键字class时默认的继承方式是private,使用struct时默认的继承方式是public,不过
最好显示的写出继承方式。
2. 在实际运用中一般使用都是public继承,几乎很少使用protetced/private继承,也不提倡
使用protetced/private继承,因为protetced/private继承下来的成员都只能在派生类的类里
面使用,实际中扩展维护性不强。
3. 基类private成员在派生类中是不能被访问,如果基类成员不想在类外直接被访问,但需要在
派生类中能访问,就定义为protected。可以看出保护成员限定符是因继承才出现的。
4.根据上面这个表格其实可以发现,我们继承的时候是去取最小的访问限定。比如一个函数的权限是protected用public方式继承后访问限定任然是protected。

子父类成员重命名

子类和父类中有同名成员,子类成员将屏蔽父类对同名成员的直接访问,这种情况叫隐藏,
也叫重定义。(在子类成员函数中,可以使用 基类::基类成员 显示访问)

class peopel {
protected:
	string name="111";
};

class teacher : public peopel {

	void show()
	{
		cout <<name<<peopel::name;
	}

protected:
	string name="222";
};

如果我们不指定就是子类里面的name

派生类的默认成员函数

1.对于构造函数,父类不显示的写,会去调用自己的默认构造,子类回去调用自己的默认构造,注意这个过程是先完成父类的构造,再完成子类的构造。

如:

class Person {
public:
	Person(const string& name="牢大") :
	_name(name)
	{}
	Person(const Person& data): _name(data._name)
	{}

	virtual~Person() {
	};
protected:
	string _name;
};


class Student :public Person {
public:
	Student( const string& name="", const string& id="") : _id(id) {}
	Student(const Student&data):Person::Person(data),_id(data._id){}


	void Show()
	{
		cout << _id << _name;
	}
	virtual~Student() {};
protected:
	string _id;
};

void Test2()
{
	Student st1("zgw", "444");
	st1.Show();
}

这里我们就算是写了这个参数,也只会去执行无参的默认构造。

只有当我们去显示的写了传参才有用。

2.拷贝构造同上。

3.析构函数,派生类对象析构清理先调用派生类析构再调基类的析构。因为后续一些场景析构函数需要构成重写,重写的条件之一是函数名相同(这个我后面会讲解)。那么编译器会对析构函数名进行特殊处理,处理成destrutor(),所以父类析构函数加virtual的情况下,子类析构函数和父类析构函数构成隐藏关系。这里有一些多态的知识。
 

class Person {
public:
	Person(const string& name="牢大") :
	_name(name)
	{}
	Person(const Person& data): _name(data._name)
	{}

	~Person() {
		cout << "~Person()" << endl;
	};
protected:
	string _name;
};


class Student :public Person {
public:
	Student( const string& name="", const string& id="") :Person::Person(name), _id(id) {}
	Student(const Student&data):Person::Person(data),_id(data._id){}


	void Show()
	{
		cout << _id << _name;
	}
	~Student() { 
		cout << "~Student()" << endl;
	};
protected:
	string _id;
};

void Test2()
{
	Student st1("zgw", "444");
	st1.Show();
}

菱形继承

当我们写出这样的代码:

这样的继承,Assistant里面就有两份Person的数据,这样就出现了数据冗余和二义性,现实世界其实有这种场景如一个导员既是学生又是老师,但是写代码不建议这么写,所以出现这种情况我们一般用虚继承

如:

class person
{
public:
	string _name; // 姓名
};
class student : virtual public person
{
protected:
	int _num; //学号
};
class Teacher : virtual public person
{
protected:
	int _id; // 职工编号
};
class Assistant : public student, public Teacher
{
protected:
	string _majorCourse; // 主修课程
};

void Test3()
{
	Assistant a;
	a._name = "peter";
	cout << a._name;
}

这样就不会出现二义性。

小tip

1.基类定义了static静态成员,则整个继承体系里面只有一个这样的成员。无论派生出多少个子
类,都只有一个static成员实例 。

2.友元函数不能被继承。

标签:name,继承,成员,c++,class,Person,菱形,public
From: https://blog.csdn.net/zgwnb666/article/details/140292461

相关文章

  • 05day--C++日期类的实现与取地址运算符的重载
    这里写目录标题5.3⽇期类实现6.取地址运算符重载6.1const成员函数6.2取地址运算符重载5.3⽇期类实现Date.h#pragmaonce#include<iostream>usingnamespacestd;#include<assert.h>classDate{//友元函数声明friendostream&operator<<(ostream&......
  • C++11标准库<chrono>、<future>、 <atomic>、<condition_variable>、<mutex>、<t
    目录<chrono>时间间隔duration常用的duration时间点time_point时钟system_clock&steady_clocksystem_clock代码举例steady_clock(秒表)例程:转换函数1.duration_castDescription:duration支持隐式转换的规则2.time_point_cast<thread>this_thread命名空间1.get_id()2.sleep_f......
  • C++类和对象 前篇
    C++类和对象基础部分​众所周知,C语言是一门面向过程的语言,面向过程简单来说就是直接使用各种函数和数据来解决一件事。而面向对象是谁来使用函数和数据去解决一件事。​C++是一门既可以面向对象也可以面向过程的语言,它能够兼容C语言,并且对C语言进行了许多优化升级,其中......
  • C++知识备忘及面试指导
    一、C++基础1.C和C++有什么区别?C语言C语言是纯面向过程的语言,不支持面向对象,函数名字不会被改编(函数不能重载)C语言的结构体只支持成员变量,不支持成员函数,成员没有访问控制(即没有publicprotectedprivate)C++C++是C语言的超集,同时支持面向过程和面向对象(类)函数名字编译......
  • C++利用类和对象封装立方体面积和体积
    C++利用类和对象封装立方体面积和体积1、说明2、代码3、总结1、说明C++利用类和对象进行封装立方体的面积和体积,对学过的知识进行总结,本代码并非原创。2、代码#include<iostream>#include<time.h>#include<string.h>#include<ctime>usingnamespacestd;//立......
  • C++ 小苹果
    题目描述小Y的桌子上放着 n 个苹果从左到右排成一列,编号为从 1 到 n。小苞是小Y的好朋友,每天她都会从中拿走一些苹果。每天在拿的时候,小苞都是从左侧第 1 个苹果开始、每隔 2 个苹果拿走 1 个苹果。随后小苞会将剩下的苹果按原先的顺序重新排成一列。小苞想......
  • c++ 勾股数
    题目描述输入整数R,输出小于等于R的满足X²+Y²=Z²的所有正整数X,Y,Z输入格式输入一个实数:R(1<=R<=100)输出格式输出一个整数表示共有多少组满足条件的勾股数样例输入10样例输出2代码如下#include<bits/stdc++.h>//万能头文件usingnamespacestd;i......
  • Hash表(C++)
        本篇将会开始介绍有关于unordered_map和unordered_set的底层原理,其中底层实现其实就是我们的Hash表,本篇将会讲解两种Hash表,其中一种为开放定址法,另一种为hash桶,在unordered_map和unordered_set的底层实现中主要是使用的是hash桶。    本......
  • c++ 计算mp3时长
    #include<stdio.h>#include<iostream>#include<fstream>#include<string>usingnamespacestd;structID3V2{ chartag[3]; charversion; charsubVersion; charflag; charsize[4];};constintbitrateIndex[16][5]={ {......
  • 【C++编程】数组、函数、结构体、指针、类
    数组:存储一个固定大小的相同类型元素的顺序集合声明、初始化:typearrayName[size0][size1]...={{value00,value01,...},{value10,value11,...},...};intmy_array[2][3]={{1,2,3},{4,5,6}};访问数组元素:arrayName[index0][index1]...;intget_eleme......