c++继承和派生(1)

这篇具有很好参考价值的文章主要介绍了c++继承和派生(1)。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

目录

1.含义:从不同层面看的,同一种意思

2. 继承的使用场景 

1.  共同之处 

2.  迭代更新 

3.  代码重构 

3. 继承的基本语法 

4. 继承了什么 

1. 查看占用内存大小

2.  使用vs自带的功能查看类的内存分布

布局: 

3. 结果 

5. protected  -- 子类的特权

1)  三个访问权限 

2)子类的特权

3)同等对待 --  私有属性

4)总结 

6. 有父才有子  --  构造子类时,先构造其父类 

1)根据代码看 

2)调用哪个构造函数 

3)自己指定调用哪个构造函数。 

4)为什么要调用父类的构造函数 

7. 父与子有不同  --  子类中定义自己的成员

1)名称覆盖:

2)子类重写函数和父类不是同一个函数 

指向成员函数的函数指针: 

8. 家有家规 --  继承的三种方式 

1)public继承 

2)protected继承 

3)private继承 

4)继承方式和访问权限的区别 


1.含义:从不同层面看的,同一种意思

继承:  子类继承于父类。 

派生:  父类派生出子类。

2. 继承的使用场景 

1.  共同之处 

我们平时创建的类,如果两个类之间存在某种关系,或者说几个类之间具有一些共同的函数或者变量。那么就可以考虑将共同部分写成父类,使用这些函数和变量的类直接从父类继承就可以,避免写重复的代码。 

比如:写一个男孩类和一个女孩类,对于男孩和女孩,他们都有吃喝玩乐的方法,姓名,年龄等成员。这时候,可以将这些公有的部分设置成一个人类,让男孩和女孩类直接继承。 

2.  迭代更新 

如果我们之前写的类,需要更新新的功能,我们不需要去修改源码,直接继承之前那个类然后在子类中实现新的功能就可以了 

3.  代码重构 

就是修改之前写的没用继承的代码, 使用继承,提高代码的质量。

3. 继承的基本语法 

Father类:

class Father {
public:
	Father();
	Father(const char* name, int age);
private:
	string name;
	int age;
};

Son类:

class Son :public Father {
public:
	Son();
};

Son类继承了Father类,class Son : public Father  ,  在子类的后面加:,然后继承的方式public,然后父类Father。

4. 继承了什么 

那么子类到底从父类中继承了什么呢? 

	Father f("父类", 20);

	Son s;   

	cout << sizeof(f) << endl;
	cout << sizeof(s) << endl;

1. 查看占用内存大小

使用上面的Father类和Son类创建对象,计算大小。  注意:子类中只有无参构造。 

我们定义父类和子类对象,打印出两个对象的大小。 --  发现两个类的内存大小都是一样的。

 c++继承和派生(1),c++,开发语言

2.  使用vs自带的功能查看类的内存分布

上面可能还不太直观,我们可以直接查看类的分布 

步骤: 1. 在项目名右键,选择属性    2.   选择c/c++,选择命令行  3. 然后添加 

 /d1 reportSingleClassLayoutSon -- 表示打印单类的布局。 想要打印哪个类的布局就在后面写

哪个类的名字。4. 确定  5. 编译代码,在输出窗口就能看到相应类的代码了。 

c++继承和派生(1),c++,开发语言

布局: 

c++继承和派生(1),c++,开发语言  

上面就是子类Son的布局,

第一行表示,基类(就是父类)为Father, 第二行是成员变name(string类型在64为os中占40个字节),第三行是一个age变量(int 类型占4个字节)。 第四行是内存对齐(4个字节)。  

3. 结果 

你会发现,name和age是Father类里面的属性。 

其实子类可以从父类中继承,除父类构造函数析构函数外的所有成员都会被子类继承。 

那上面为什么没有其它成员函数呢,因为,成员函数并不是和对象存储在一起的。 

为什么不继承构造函数和析构函数:因为构造函数和析构函数的名字是父类的,继承到子类也没用。 

5. protected  -- 子类的特权

1)  三个访问权限 

public:          公有权限,在类内,子类内和类外都可以直接访问类中定义的成员 

private:      私有权限,只能在类内直接访问,在类外和子类中都无法直接访问,只能使用提供                         的public接口简介访问 

protected: 保护权限,可以直接在类内和子类中访问,无法在类外直接访问。

2)子类的特权

如果有一些数据,希望子类可以直接访问,不希望类外直接访问,那么定义成private就行。

3)同等对待 --  私有属性

对于private的属性,子类和外界都是一样的,都无法访问。但是,私有属性子类也继承了(前面的例子中),但是,编译器规定,由于这些属性是继承于父类的私有属性,所以在子类的内部是无法直接访问的。(要想访问也得调用父类提供的公共接口) 

4)总结 

对于子类,父类中的private,和public属性都可以在子类中直接访问,但是私有属性不可以。 

6. 有父才有子  --  构造子类时,先构造其父类 

1)根据代码看 

先看一段代码:  我们分别在子类和父类的构造函数中输出__FUNTION__(自己的函数名字),然后在主函数中,创建子类,来看一下子类和父类的构造函数调用情况 

int main(void) {

	Son s;   

	system("pause");

	return 0;
}

 c++继承和派生(1),c++,开发语言

会发现,创建子类对象时,会先调用其父类的构造函数。 

2)调用哪个构造函数 

上面说到,要想构造子类对象,就会先调用父类的构造函数,但是构造函数有默认的,有参数的,应该调用哪一个呢? 

如果我们没有指定,编译器默认会调用父类的默认构造函数。(你可以在父类中只写有参数的构造,然后在子类构造函数处,就会报错--父类没有默认构造函数)从这一点就可以看出,当调用子类构造函数的时候,并且在未指定的情况下,编译器会默认调用父类的默认构造函数。 

3)自己指定调用哪个构造函数。 

Son::Son(const char* name, int age):Father(name,age){

	std::cout << __FUNCTION__ << std::endl;

	this->name = name;
	this->age = age;
}

我们可以看到,在子类构造函数的右侧 : 父类名(相应构造函数的参数),这样就可以指定当我们调用子类有参构造函数创建子类对象时, 会调用父类的有参构造函数。

当然,我们此处是在有参数构造处指定的,对于其它的构造函数,还是会调用父类的默认构造函数。 

4)为什么要调用父类的构造函数 

1. 一种解释,这是c++的语法的规定,也符合正常的环境,先有父亲再有儿子。

2. 另一个解释,就是我们一般会将属性设置为私有的,这样,在子类中无法直接访问从父类继承的成员,这时候就无法对这些属性进行初始化或者赋值了,那怎么办?

我们可以调用父类的构造函数来初始化这些数据,因为私有的变量,是可以在本类的函数中访问的。 所以,我们在:后写的,是函数调用,调用父类构造函数。 

3. 所以c++会在调用子类的构造函数的时候调用父类的构造函数,如果不写默认会调用默认构造函数。(前提,这些构造函数必须存在,否则会出错) 

7. 父与子有不同  --  子类中定义自己的成员

 子类不仅可以继承父类的成员,当然也可以有自己的成员。

class Son :public Father {
public:
	Son();
	Son(const char* name, int age);
private:
	int play;
};

 子类Son中定义了自己的数据成员,int play,当然也可以定义自己的成员函数。

1)名称覆盖:

其实类我们可以看做一个作用域,子类作用域是嵌套在父类作用域中的。 

c++继承和派生(1),c++,开发语言

1. 当我们,使用子类访问成员函数或者成员变量的时候,会先从子类的作用域找,没有的话会从父类的作用域中去找。(逐渐往外) 

 2. 当我们在子类中定义和父类之外的同名的变量或者函数的时候,那么就会对外部定义的同名变量和函数进行覆盖,使用子类对象访问的时候,会访问自己的对象和函数。(同名时) 

 3. 对于函数,只要函数名字相同,就会覆盖外界的所有函数,无论函数的参数是否一样。(就是不同作用域只有覆盖,同一作用域下才有重载)

2)子类重写函数和父类不是同一个函数 

往往子类有时会对父类的函数进行重写,虽然它们名字相同但是并不是同一片内存(其实编译之后就不同了)。 

我们可以通过查看父类和子类的同名函数的地址来查看是否是同一个函数

指向成员函数的函数指针: 

C语言中我们学习过指向函数的函数指针,这里同理,定义一个函数指针,指向成员函数,然后就可以查看成员函数的地址。 

语法: 函数返回值  (函数所在类名::*指针变量)   =   &函数所在类名::函数名 

class Father {
public:
	void address();
protected:
	int age;
};

class Son :public Father {
public:
	void address();

private:
	int link;

};

 
void Father::address() {

	void (Father::*p)() = &Father::address;

	printf("%p\n",p);
}

void Son::address() {
	void (Son:: * p)() = &Son::address;

	printf("%p\n", p);
}

int main(void) {
	Father f;
	Son s;

	f.address();

	s.address();

	system("pause");

	return 0;
}

8. 家有家规 --  继承的三种方式 

前面继承语法中有一个访问方式public,还有两种,private,protected,这看起来和访问权限很类似,实则是不一样的。 

1)public继承 

public继承方式,继承父类的成员时, 不会改变父类成员的访问权限。

private  ->  private     public -> public    protected -> protected 

2)protected继承 

protected继承方式,继承父类的成员时,会将public转换为protected,其它权限不变 

private ->  private       public -> protected    protected -> protected 

3)private继承 

provate继承方式,继承父类的成员时,会将所有访问权限都转换为private 

private -> private       public ->  private    protected -> private 

4)继承方式和访问权限的区别 

虽然继承方式和访问权限都是三个且都是public,private,protected。但是却不相同。 

继承方式可以说是限制外界的。 

对于子类,继承方式无论是什么,在类的内部都可以直接访问父类的public,protected的成员。 

那要那么多继承方式做什么?  --  是用来限制外界的。

我们在外界定义子类的对象,通过子类对象调用继承的成员,如果是public方式,那就可以调用对应父类的public成员,protected继承和private继承是不可以在类外进行访问的。   文章来源地址https://www.toymoban.com/news/detail-796284.html

到了这里,关于c++继承和派生(1)的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 第八站:C++面向对象(继承和派生)

     派生:由父类派生出子类 继承:子类继承父类(继承不会继承 析构函数和构造函数 : 父类的所有成员函数,以及数据成员,都会被子类继承! ) \\\"子类派生出的类\\\"会指向\\\"父类被继承的类\\\", 父类就是基类 实例1: 先创建一个父类,有私有成员数据(name,和age),成员函数,描述信息,有参的

    2024年01月19日
    浏览(36)
  • 【浅尝C++】继承机制=>虚基表/菱形虚继承/继承的概念、定义/基类与派生类对象赋值转换/派生类的默认成员函数等详解

    🏠专栏介绍:浅尝C++专栏是用于记录C++语法基础、STL及内存剖析等。 🎯每日格言:每日努力一点点,技术变化看得见。 我们生活中也有继承的例子,例如:小明继承了孙老师傅做拉面的手艺。继承就是一种延续、复用的方式。C++为了提高代码的可复用性,引入了继承机制,

    2024年04月10日
    浏览(38)
  • 头歌Educoder实验:C++ 面向对象 - 类的继承与派生

    第1关:公有继承 —— 学生信息类 任务描述 本关任务:采用公有继承设计学生信息类。 相关知识 继承 继承是使代码可以复用的重要手段,也是面向对象程序设计的核心思想之一。简单的说,继承是指一个对象直接使用另一对象的属性和方法。 C++ 中的继承关系就好比现实生

    2024年02月04日
    浏览(108)
  • 【C++入门到精通】C++入门 —— 继承(基类、派生类和多态性)

    前面我们讲了C语言的基础知识,也了解了一些数据结构,并且讲了有关C++的命名空间的一些知识点以及关于C++的缺省参数、函数重载,引用 和 内联函数也认识了什么是类和对象以及怎么去new一个 ‘对象’ ,也了解了C++中的模版,以及学习了几个STL的结构也相信大家都掌握

    2024年02月11日
    浏览(34)
  • <c++> 类的继承 | 基类与派生类 | 构造函数与析构函数

    🚀 个人简介:CSDN「 博客新星 」TOP 10 , C/C++ 领域新星创作者 💟 作    者: 锡兰_CC ❣️ 📝 专    栏: 从零开始的 c++ 之旅 🌈 若有帮助,还请 关注➕点赞➕收藏 ,不行的话我再努努力💪💪💪 c++ 面向对象三大特性: 封装,继承,多态 。通过本文我们将了解什么是类的

    2023年04月20日
    浏览(38)
  • 【C++】面向对象编程(二)面向对象的编程思维:virtual虚拟调用、继承、protected成员、派生类与基类

    默认情形下,成员函数的解析都是编译时静态进行。如果要让成员函数的解析在程序运行时动态进行,需要在成员函数的声明前加上virtual: 虚函数的作用: 用基类的指针指向不同的派生类的对象时,基类指针调用其虚成员函数,会调用 真正指向对象的成员函数 ,而

    2024年02月07日
    浏览(35)
  • 【期末不挂科-C++考前速过系列P4】大二C++实验作业-继承和派生(3道代码题)【解析,注释】

    前言 大家好吖,欢迎来到 YY 滴C++考前速过系列 ,热烈欢迎! 本章主要内容面向接触过C++的老铁 主要内容含: 欢迎订阅 YY 滴C++专栏!更多干货持续更新!以下是传送门! YY的《C++》专栏 YY的《C++11》专栏 YY的《Linux》专栏 YY的《数据结构》专栏 YY的《C语言基础》专栏 YY的《

    2024年01月17日
    浏览(36)
  • C# 什么是继承和派生

    在 C# 中,继承(Inheritance)是一种机制,它允许一个类(子类)从另一个类(父类)中继承属性和方法。这种关系使得子类可以重用父类的代码,同时可以在子类中添加或修改属性和方法。继承有助于减少代码重复和提高代码的可维护性。 派生(Derivation)是指使用继承机制

    2024年02月09日
    浏览(29)
  • 实验三 Java类的继承与派生

    Student IStudentDAO StudentDAOImpl MainClass

    2024年02月05日
    浏览(41)
  • c、c++、java、python、js对比【面向对象、过程;解释、编译语言;封装、继承、多态】

    目录 内存管理、适用 区别 C 手动内存管理:C语言没有内置的安全检查机制,容易出现内存泄漏、缓冲区溢出等安全问题。 适用于系统级编程 C++ 手动内存管理:C++需要程序员手动管理内存,包括分配和释放内存,这可能导致内存泄漏和指针错误。 适用于游戏引擎和系统级编

    2024年02月08日
    浏览(64)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包