C++继承(2)——赋值转换、隐藏特性以及作用域

这篇具有很好参考价值的文章主要介绍了C++继承(2)——赋值转换、隐藏特性以及作用域。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

目录

一.子类和父类对象的赋值转换

子类对象赋值父类对象的另外两种方式:

总结:

二.父类与子类的作用域

1. 在继承体系中基类和派生类都有独立的作用域。

        例:

2.作用域练习

        练习1:

解决方法:

一.子类和父类对象的赋值转换

先来看一个案例:变量间的赋值

int main(){
	int a;
	double b = 10.22;

	a = b;    //赋值转换
	return 0;
}

        在上面这个代码中,有两个变量a,b,这两个变量类型分别为整型和浮点型,而变量b赋值给变量a,变量b的值10.22在赋值给变量a的过程中,产生一个临时变量,10.22拷贝一份给了临时变量,在这个临时变量中进行类型转换,10.22-->10,然后临时变量的值10再赋值给变量a。 

C++继承(2)——赋值转换、隐藏特性以及作用域,C++,c++

学习了继承的特性后,我们将通过这个案例看看子类和父类对象的赋值转换过程:

class Person {
public:
	void Print() {
		cout << "Person类对象的成员属性:" << endl;
		cout << _age << endl;
		cout << _name << endl;
		cout << _hight << endl;
		cout << _address << endl;
		cout << endl;
        }
public:
	int _age;
	string _name;
	int _hight;
	string _address="TaiYuan";

};

class Student:public Person{
public:
	int _className;
	string _grade;
};

int main(){
    Person p1;
	p1._name = "小曹";
	p1._age = 21;
	p1._hight = 172;
	p1.Print();

	Student s1;
	s1._name = "小王";
	s1._age = 22;
	s1._hight = 170;
	s1._grade = "大三";

	//将子类对象的成员值复制给父类对象
	p1 = s1;			
}

        此时p1对象的成员值就是s1的成员值,但p1并不会有Student子类所创_grade,_className成员变量值,在赋值操作中,子类对象只会将它继承过来的成员值重新赋回给父类对象!!!

 C++继承(2)——赋值转换、隐藏特性以及作用域,C++,c++

 这就是子类对象对父类对象的赋值转换——支持向上转换,不支持向下转换。

        也就是说父类对象不能赋值给子类对象,因为父类对象中并没有子类对象的_classname、_grade成员值,那它就不能赋!!!

子类对象赋值父类对象的另外两种方式:

C++继承(2)——赋值转换、隐藏特性以及作用域,C++,c++

创建子类对象并将其成员初始化,而父类对象是采用引用的方式进行向上转换 

运行结果: 

C++继承(2)——赋值转换、隐藏特性以及作用域,C++,c++


C++继承(2)——赋值转换、隐藏特性以及作用域,C++,c++

运行结果: 

C++继承(2)——赋值转换、隐藏特性以及作用域,C++,c++

总结:

        子类对象可以赋值给父类的对象、赋给基类的指针、赋给基类的引用。这里有个形象的说法叫“切片”或者“切割”。寓意子类将从父类中继承过来的的那部分成员值切下来赋值给父类对象/指针/引用过去。

二.父类与子类的作用域

1. 在继承体系中基类和派生类都有独立的作用域。

        例:
class Person {
public:
	void Print() {
		cout << "父类的Print函数:" << endl;
		cout << "姓名:" << _name << endl;
		cout << "年龄:" << _age << endl;
		cout << "性别:" << _sex << endl;
		cout << endl;
	                }
	int Add(int age=100) {
		return _age = ++age;
	}
public:
	int _age=26;
	string _name="王丽";
	string _sex="女";
};

class Student :public Person {
public:
	void Print() {
		cout << "子类的Print函数:" << endl;
		cout << "学号:" << _id << endl;
		cout << "性别:" << _sex << endl;
		cout << "班级:" << _ClassName << endl;
		cout << endl;
	            }
public:
	int _id=202001;
	string _ClassName="优秀2班";
	string _sex="男";
};


int main() {
	Person p;
	p.Print();	
	Student s1;
	s1.Print();	
	
	s1._age = s1.Add();	
	cout << "对象s1的成员变量_age值为:"<<s1._age << endl;

	s1.Person::Print();			

	return 0;
}

代码解析:从上图代码中可知,父类和子类都各有一个Print()成员函数,而且子类对象和父类对象都调用了Print()函数。 

运行结果: 

C++继承(2)——赋值转换、隐藏特性以及作用域,C++,c++

        从结果我们发现:子类对象和父类对象调用Print()函数时,都调用的是自家类中的Print(),并没有发生子类调用父类Print()函数的情况。 

        那么就可以从中得出一个规律:当在父类和子类中都有同名的函数,且这俩类对象都执行调用这个同名函数时,编译器会优先调用该对象自家类中的同名函数,若该类对象中没有该名称的函数,编译器就会从子类继承过父类中的成员函数中寻找该名称函数。

        想到这是不是有一点点熟悉感,这不就是变量赋值的情况吗?编译器局部优先法,局部没有就去全局找。

测试代码:

C++继承(2)——赋值转换、隐藏特性以及作用域,C++,c++

C++继承(2)——赋值转换、隐藏特性以及作用域,C++,c++

C++继承(2)——赋值转换、隐藏特性以及作用域,C++,c++

以上就是编译器对子类对象调用函数的详细步骤。 

那么又有新的问题了,子类对象就是想调用父类中的Print()函数怎么办?

        一般的方式是行不通的,毕竟子类中的Print()摆在那里,而且对于父类子类的同名函数有个“隐藏”机制,子类会将父类继承过来的成员函数做隐藏操作,也就是说表面上子类只存在一个Print函数,虽然子类有父类的Print,但是被子类给藏起来了,不到万不得已不会用。

       

         若就是想调用父类的Print(),就得在调用前加作用域限定符!

C++继承(2)——赋值转换、隐藏特性以及作用域,C++,c++

所以隐藏只针对于父类子类都各有一个相同名称的成员函数!!! 


2.作用域练习

        练习1:
class Person {
public:
	void Func() {
		cout << "Func():" << endl;
		cout << endl;
	            }
public:
	int _a;
	string _b;
};

class Student :public Person {
public:
	void Func(int i) {
		cout << "Func(int i)->:" << endl;
        	}
public:
	int _id;
	double _result;
};

int main() {
	Student s2;
	s2.Func();

请问执行代码时会发生什么?

A:造成重载    B:造成重写    C:隐藏/重定义        D:编译出错 

习题解析:

        如上代码可知:Person类的Func函数是无参函数,而子类Student类的Func函数是带参函数
基于此,若s2.Func();编译器默认会优先调用子类本类的Func函数,但是调用时发现,子类的Func函数需要参数带入,而对象s2调用时,并没有传入实参,所以结果:是选C和D:既会发生隐藏情况,又有编译出错。

        总结描述:s2调用的Func()未传参数,导致编译器找不到符合无参的Func函数,报了编译错误,且在此情况中,子类隐藏了从父类继承来的Func()带参函数,也就是说s2想调用的就是从父类继承来的成员函数,但被子类隐藏了,也就调不成,进而出现编译错误。、文章来源地址https://www.toymoban.com/news/detail-619572.html

解决方法:
    //解决方法1:
	    s2.Person::Func();
	//解决方法2:
	    s2.Func(10);

到了这里,关于C++继承(2)——赋值转换、隐藏特性以及作用域的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

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

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

相关文章

  • C++三大特性之一:继承

    C++三大特性:继承、多态和封装。继承是面向对象编程的一个核心概念,它允许我们根据一个已存在的类(基类或者叫父类),创建一个新的类(派生类或者叫子类),这个新的类继承了类的属性和行为。 1.继承格式。 class 子类名 :继承属性(publicprotectedprivate)父类名{

    2024年04月25日
    浏览(27)
  • C++ 面向对象三大特性——继承

    ✅1主页:我的代码爱吃辣 📃2知识讲解:C++ 继承 ☂️3开发环境:Visual Studio 2022 💬4前言:面向对象三大特性的,封装,继承,多态,今天我们研究研究 C++的继承 。 目录 一.继承的概念及定义 1.继承的概念  2.继承的定义 二. 继承关系和访问限定符  三.基类和派生类对象赋

    2024年02月12日
    浏览(66)
  • 【C++】三大特性 --- 继承的详细讲解

    目录 1.继承的概念及定义 1.1 继承的概念 1.2 继承定义 1.2.1定义格式 1.2.2继承关系和访问限定符 1.2.3继承基类成员访问方式的变化 2.基类和派生类对象赋值转换 3.继承中的作用域 4.派生类的默认成员函数 5.继承与友元 6.继承与静态成员 7.复杂的菱形继承及菱形虚拟继承 8.继承的

    2024年02月05日
    浏览(46)
  • 面向对象的三大特性之继承(C++)

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

    2024年02月06日
    浏览(49)
  • C++核心编程—类和对象,类的三大特性——封装、继承、多态

    纵有疾风起,人生不言弃。本文篇幅较长,如有错误请不吝赐教,感谢支持。 ①什么是对象? 生活中有各种各样的 事物 ,如人、动物、植物等在C++中将这些称为对象。 对象多种多样, 各种对象的属性也不相同 。 例如狗的品种,毛色,年龄等 各个对象都有自己的行为 ,例

    2024年02月07日
    浏览(62)
  • 【C++】万字一文全解【继承】及其特性__[剖析底层化繁为简](20)

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

    2024年02月01日
    浏览(75)
  • 【C++庖丁解牛】面向对象的三大特性之一多态 | 抽象类 | 多态的原理 | 单继承和多继承关系中的虚函数表

    🍁你好,我是 RO-BERRY 📗 致力于C、C++、数据结构、TCP/IP、数据库等等一系列知识 🎄感谢你的陪伴与支持 ,故事既有了开头,就要画上一个完美的句号,让我们一起加油 需要声明的,本节课件中的代码及解释都是在vs2013下的x86程序中,涉及的指针都是4bytes。如果要其他平台

    2024年04月10日
    浏览(56)
  • C++实战Opencv第二天——色彩空间转换函数和opencv中图像对象创建与赋值(从零开始,保姆教学)

    OpenCV是一个强大的计算机视觉库,使用C++作为主要编程语言,对于图像处理和计算机视觉领域具有重要意义。其提供了丰富的功能和算法,使得开发者能够快速实现各种图像处理和计算机视觉应用。OpenCV C++为图像处理和计算机视觉领域的开发者提供了一个高效、稳定的工具。

    2024年02月20日
    浏览(41)
  • C++学习Day08之类模板碰到继承的问题以及解决

    必须要指定出父类中的T数据类型,才能给子类分配内存 正确使用 : 输出: 输出: 在类模板碰到继承的问题时,要指定出父类中的T数据类型,才能给子类分配内存

    2024年02月22日
    浏览(32)
  • c++ 11 新特性 不同数据类型之间转换函数之reinterpret_cast

    一.不同数据类型之间转换函数 reinterpret_cast 介绍 reinterpret_cast 是C++中的一种类型转换操作符,用于执行低级别的位模式转换。具体来说, reinterpret_cast 可以实现以下功能: 指针和整数之间的转换 :这种转换通常用于在指针中存储额外信息,或者在特定平台上进行底层操作。

    2024年03月09日
    浏览(40)

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

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

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

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

二维码1

领取红包

二维码2

领红包