C++继承详细介绍

 更新时间:2022年10月18日 14:49:21   作者:是星星鸭  
我们都知道面向对象语言的三大特点是:**封装,继承,多态。**之前在类和对象部分,我们提到了C++中的封装,那么今天呢,我们来学习一下C++中的继承

前言

可能会涉及到汇编的知识,不过这没有关系,肯定能看懂,看不懂留言,我再做解释。

使用到的工具是vs2010。

本节只讲继承的特点,公有私有多态等内容暂且不讲,以后会细说。

一、什么是继承

继承就是数据的复制

概念模糊、直接上代码:

#include <stdio.h>
#include <Windows.h>
struct Master            // 父类(基类)
{
	int a;
	int b;
};
struct Slave:Master      // 子类(派生类)
{
	int c;
	int d;
};
int main()
{
	Slave slave;
	slave.a = 1;
	slave.b = 2;
	slave.c = 3;
	slave.d = 4;
	int x = sizeof(slave);
	system("pause");      // 此处下断点查看x的大小(子类的大小)
	return 0;
}

运行,查看x的值:

16,这足以说明slave是拷贝了一份a和b给slave子类的。

查看汇编:

可以看出继承就是数据的复制

二、派生类和基类的成员重复问题

1、派生类和基类的成员可以重复吗?

2、重复的话是使用的哪一个类的成员呢?

解答如下:

1、派生类和基类的成员可以重复吗?

可以。

证明:

#include <stdio.h>
#include <Windows.h>
struct Master
{
	int a;
	int b;
};
struct Slave:Master
{
	int a;
	int d;
};
int main()
{
	Slave slave;
    printf("%d \n",sizeof(slave));
	system("pause");           
	return 0;
}

运行:

不仅可以,而且slave类的大小依旧是16字节;

这说明了子类的a和父类的a是分开的,父类的a依旧被拷贝到了子类,尽管子类已经有成员a;

2、重复的话是使用的哪一个类的成员呢?

这样就不要使用变量来测试了,因为变量无法输出内容,很难分辨出是父类还是子类的,所以我们使用函数。

如下:

#include <stdio.h>
#include <Windows.h>
struct Master
{
	void test()
	{
		printf("这是父类的测试。\n");
	}
};
struct Slave:Master
{
	void test()
	{
		printf("这是子类的测试。\n");
	}
};
int main()
{
	Slave slave;
	slave.test();
	system("pause");
	return 0;
}

定义一父一子,类中都定义了test函数,那么子类的对象会调用谁的呢?

运行如下:

子类调用了子类的。

父类的对象会调用谁的呢?

测试如下:

运行:

父类调用父类。

可以看到,对象的默认调用都是本类自己定义的函数。

父类调用子类方法

父类可以调用子类方法吗?如何调用?子类又如何调用父类呢?

父类可以调用子类方法,步过需要一些手段;子类可以直接调用父类

先看一张图:

从这张图我们可以得知,子类包含了父类中允许继承的所有内容;但父类不包含任何子类的东西。

所以,子类可以直接调用父类是应该的,如下:

#include <stdio.h>
#include <Windows.h>
struct Master
{
	void test()
	{
		printf("这是父类的测试。\n");
	}
};
struct Slave:Master
{
	void test()
	{
		printf("这是子类的测试。\n");
	}
};
int main()
{
	Slave slave;
	slave.test();
	slave.Master::test();        // 声明调用父类的内容即可
	system("pause");
	return 0;
}

运行如下:

可以看到,子类正常的调用了父类的方法;

如果父类直接调用子类的呢?

如下:

直接调用的话是不被允许的。

不过可以通过其他方法进行调用;

父类调用子类

我们知道,纯虚函数是必须要子类进行实现的,如果父类定义了纯虚函数,子类不进行实现,就会报错;我们可以通过这一点,让父类定义纯虚函数,子类来实现这个纯虚函数;然后父类定义指针(纯虚类就是接口类,无法定义对象,可以定义指针)来指向子类,调用子类的函数。

如下:

#include <stdio.h>
#include <Windows.h>
struct Master
{
	virtual void test() = 0;		 // 父类定义纯虚函数
};
struct Slave:Master
{
	void test()						 // 子类实现纯虚函数
	{
		printf("这是子类的测试。\n");
	}
};
int main()
{
	Slave slave;
	slave.test();					 // 子类正常调用
	// Master master;				 // 不可以定义对象,会出错。
	Master *master = &slave;		 // 可以定义指针指向子类
	master->test();
	system("pause");
	return 0;
}

运行:

成功调用。

当然还有其他方法可以让父类调用子类,不过本文章只讲继承,不深入其他内容;大家感兴趣的话可以自己百度看看。

三、继承不仅仅局限于父类

怎么理解这个标题呢?就是说,不单单是父类可以有派生类,子类也可以有派生类。

如果子类有派生类,那么子类的派生类仅仅有父类的成员,还是既有父类的成员也有父类的父类成员?

观点:子类的派生类,即会拥有父类的公有成员也会拥有父类的父类的公有成员。

文字模糊,看图:

通过这张图我们可以知道:Son调用Slave的函数或者Master的函数可以直接调用;

Son包含Master和Slave所有公有成员、Slave只包含Master的公有成员、Master只包含自己的成员。

论证如下:

直接测试类所占用字节数就行了,如下:

#include <stdio.h>
#include <Windows.h>
struct Master
{
	int a;
	int b;
};
struct Slave:Master
{
	int c;
	int d;
};
struct Son:Slave
{
	int e;
	int f;
};
int main()
{
	int MasterSize = sizeof(struct Master);
	int SlaveSize = sizeof(struct Slave);
	int SonSize = sizeof(struct Son);
	printf("Master成员个数:\t%d\nSlave成员个数:\t\t%d\nSon成员个数:\t\t%d\n",MasterSize/4,SlaveSize/4,SonSize/4);
	system("pause");
	return 0;
}

Slave继承Master,Son继承Slave

三个类的成员都是int类型,所以通过类的字节数/4就可以知道这个类有几个成员

运行如下:

论证成功。

四、多重继承

就是说子类不单单可以继承一个父类,可以继承多个。

如下:

#include <stdio.h>
#include <Windows.h>
struct Master                 // 第一个父类
{
	int a;
	int b;
};
struct Slave                  // 第二个父类
{
	int c;
	int d;
};
struct Son:Slave,Master       // 两个父类
{
	int e;
	int f;
};
int main()
{
	int MasterSize = sizeof(struct Master);
	int SlaveSize = sizeof(struct Slave);
	int SonSize = sizeof(struct Son);
	printf("Master成员个数:\t%d\nSlave成员个数:\t\t%d\nSon成员个数:\t\t%d\n",MasterSize/4,SlaveSize/4,SonSize/4);
	system("pause");
	return 0;
}

运行如下:

所以,如图:

这就是多重继承,但是多重继承增加了程序的复杂度,不建议使用 。

总结

1、什么是继承?

继承就是数据的复制

2、为什么要继承?

减少重复代码的编写

3、继承不仅仅局限于父类

4、多重继承增加了程序的复杂度,不建议使用

5、父类基类都是同一个东西,子类派生类都是同一个东西

到此这篇关于C++继承详细介绍的文章就介绍到这了,更多相关C++继承内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

相关文章

  • C语言+EasyX实现数字雨效果

    C语言+EasyX实现数字雨效果

    这篇文章主要为大家详细介绍了C语言+EasyX实现数字雨效果,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2018-11-11
  • C++编程使用findfirst和findnext查找及遍历文件实现示例

    C++编程使用findfirst和findnext查找及遍历文件实现示例

    这篇文章主要为大家介绍了C++编程如何使用findfirst和findnext查找及遍历文件实现示例,有需要的朋友可以借鉴参考下,希望能够有所帮助
    2021-10-10
  • 使用C++模拟实现2024春晚刘谦魔术

    使用C++模拟实现2024春晚刘谦魔术

    刘谦在2024年春晚上的撕牌魔术的数学原理非常简单,所以这篇文章主要为大家详细介绍了如何使用C++模拟实现这一魔术效果,感兴趣的可以了解下
    2024-02-02
  • C++直接cout指针名的含义?

    C++直接cout指针名的含义?

    今天小编就为大家分享一篇关于C++直接cout指针名的含义?,小编觉得内容挺不错的,现在分享给大家,具有很好的参考价值,需要的朋友一起跟随小编来看看吧
    2019-04-04
  • C++面试题之进制转换的实例

    C++面试题之进制转换的实例

    这篇文章主要介绍了C++面试题之进制转换的实例的相关资料,希望通过本文能帮助到大家,让大家理解掌握这样的知识,需要的朋友可以参考下
    2017-10-10
  • C语言实现成绩统计示例

    C语言实现成绩统计示例

    这篇文章主要介绍了C语言实现成绩统计示例,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教
    2022-11-11
  • C++拷贝构造函数中的陷阱

    C++拷贝构造函数中的陷阱

    这篇文章主要介绍了C++拷贝构造函数中的陷阱,拷贝构造函数大家都比较熟悉,通俗讲就是传入一个对象,拷贝一份副本。不过看似简单的东西,实际不注意的话就会产生问题,下面我们就来看看C++拷贝构造函数中都有哪些陷阱吧
    2022-01-01
  • C语言 从根本上理解数组

    C语言 从根本上理解数组

    数组是一组有序的数据的集合,数组中元素类型相同,由数组名和下标唯一地确定,数组中数据不仅数据类型相同,而且在计算机内存里连续存放,地址编号最低的存储单元存放数组的起始元素,地址编号最高的存储单元存放数组的最后一个元素
    2022-04-04
  • C语言超详细讲解函数指针的运用

    C语言超详细讲解函数指针的运用

    函数指针是一个指针变量,它可以存储函数的地址,然后使用函数指针,下面这篇文章主要给大家介绍了关于C语言进阶教程之函数指针的相关资料,需要的朋友可以参考下
    2022-06-06
  • C++ 使用模板实现一个List的实例

    C++ 使用模板实现一个List的实例

    这篇文章主要介绍了 C++ 使用模板实现一个List的实例的相关资料,需要的朋友可以参考下
    2017-05-05

最新评论