C++面对对象编程进阶(1)

面对对象编程进阶(1)

  • 1.初始化列表
  • 2.类的继承
  • 3.深挖公有、私有及保护
  • 4.友元类
  • 5.类指针

1.初始化列表

C++中类的初始化列表应用于构造函数初始化类的成员变量。其具体应用方法为:

class Student
{public:int age;string name;Student():age(0),name("ZhangSan"){}Student(int a,string b):age(a),name(b){}
};
int main()
{Student ZhangSan,LiSi(20,"LiSi");cout<<ZhangSan.name<<" "<<ZhangSan.age<<endl;cout<<LiSi.name<<" "<<LiSi.age<<endl;
}
// 输出为:ZhangSan 0
//        LiSi 20

初始化列表赋值的方法可以在创建构造函数时进行,并且这种方法也可以为初始化私有成员。初始化列表可以提高代码的执行效率和可读性,在继承问题中,我们还会继续探讨初始化列表。

2.类的继承

通俗地讲,如果有两个类A和B,假如B类可以获得A类的部分或全部的属性和方法,我们就可以称B继承了A,即B是A的派生类。除了可以从A类中获得非私有成员外,B还可以有自己独特的属性和方法(这一点和python相同),包括自己的构造函数。但是对于B类来说,初始化列表就只能给自己声明的属性赋值,不能用于给继承来的属性赋值了。下面我们看一个简单的例子:

class Student
{public:int age;string name;Student():name("ZhangSan"),age(0){}Student(int a,string b):name(b),age(a){}
};
class undergraduate:public Student
{public:string research;undergraduate():research("computer"){} // 尝试仅初始化research属性,最终不能成功undergraduate(int a,string b):research("computer") // 继承父类重构的构造函数{// name和age作为继承来的属性无法使用初始化列表赋值name=b; age=a;}
};
int main()
{undergraduate LiSi(24,"LiSi");cout<<LiSi.age<<LiSi.name<<LiSi.research<<endl;undergraduate ZhangSan;cout<<ZhangSan.age<<ZhangSan.name<<ZhangSan.research<<endl;Student WangWu(19,"WangWu");cout<<WangWu.age<<WangWu.name<<endl;
}
// 输出为:24LiSicomputer
//       20ZhangSancomputer
//       19WangWu

这段代码中,undergraduate类是Student类的派生,当我们实例化undergraduate类时,是一定会先调用基类Student的无参数构造函数的,对于LiSi实例,创建初会先在Student类的无参数构造函数中被赋值,name为ZhangSan,age为0,然后再重返undergraduate类的含参数构造函数中初始化research为computer,并修改name和age两个属性。对于ZhangSan实例,创建时首先也是会在Student类的无参数构造函数中赋初值,然后才在undergraduate类的无参数构造函数中初始化research。
这段代码值得我们仔细分析,建议大家从main函数的第一句打断点,一句一句debug。
理解了上述的代码,我们来分析一个问题,我们实例化LiSi时,会自动跳转到基类的无参数构造函数中赋初值,这个初值不是我们想要的,所以后面还要再花时间去改写,这造成了时间上的浪费。那么有没有什么办法闭麦那这个过程呢?
想解决这个问题,我们首先需要知道,undergraduate构造函数会跳转到Student中是因为代码默认派生类的构造函数继承基类的无参数构造函数。我们可以让undergraduate类的含参构造函数继承Student的含参构造函数,然后再给undergraduate类的新建成员赋初值就可以了:

class Student
{public:int age;string name;Student():name("ZhangSan"),age(0){}Student(int a,string b):name(b),age(a){}
};
class undergraduate:public Student
{public:string research;undergraduate():research("computer"){} undergraduate(int a,string b):Student(a,b),research("computer"){} // 继承父类含参构造函数
};
int main()
{undergraduate LiSi(24,"LiSi");cout<<LiSi.age<<LiSi.name<<LiSi.research<<endl;
}

其实我们也可以写出让undergraduate类的无参数构造函数继承 Student类的无参数构造函数,但是这个继承是默认的,因此我就省略了。这个例子告诉我们,无论我们是否需要,使用派生类时也都必须要调用基类的构造函数,但是带参数的构造函数是不会被自动继承到派生类中的。如果派生类需要使用带参数的构造函数,应当声明继承关系。

3.深挖公有、私有及保护

上一节我们没有提到继承的概念,因此就简单的把公有和私有成员的区别说成了是否可以在类外直接使用。然而有了继承关系我们就需要把类内和类外分的更细致。公有成员可以在任何位置直接使用;私有成员只能在基类内(或友元类内,下面会讲到)直接使用,派生类也不可以直接使用;受保护成员可以在基类、友元类和派生类内直接使用。下面我们看一个例子:

class Student
{public:int age=0;void show(){cout<<age<<name<<uni<<endl; //在基类内可以访问私有和被保护成员}private:string uni="S university";protected:string name="no";
};
class undergraduate:public Student
{public:void show_amand(){// uni="a university"; // 无法访问私有成员name="ZhangSan";age=20;cout<<age<<name<<endl;}
};
int main()
{Student ZhangSan;ZhangSan.show(); // 借由公有方法间接查看私有和被保护成员// ZhangSan.uni; // 无法访问私有成员// ZhangSan.name; // 无法访问受保护成员cout<<ZhangSan.age<<endl;undergraduate t;t.show_amand();
}

受保护和私有的方法同属性成员所受限制一样,感兴趣的小伙伴可以自己写尝试一下。

4.友元类

上一节我给大家留了个扣子,现在我们来看看友元类的情况。友元类本质上也是一个类,只不过它的权限比基类只高不低。友元类的使用必须慎之又慎,因为滥用友元类可能会危害封装性。
在A类中使用friend关键字可以声明B类是A类的友元类,友元类可以直接操作任何基类的成员,不会受到限制,并且还可以独立拥有自己的成员:

class Student
{public:string name="ZhangSan";private: // 直接以使用限制最大的私有类型为例char sex='w';friend class Teacher;
};
class Teacher // 定义友元类
{public:void access_sex(Student& aa) // 函数这样使用形参可以引用对应实例的私有内容// 可以理解成在友元类中把传递进来的实例改名{aa.sex = 'm'; // 可以访问私有成员aa.name="LiSi";cout<<aa.sex<<aa.name<<endl;}
};
int main()
{Student Zhangsan;Teacher LiSi;LiSi.access_sex(Zhangsan); // 借由友元类LiSi修改Zhansan的私有属性sexcout<<Zhangsan.name<<endl; // 通过打印公有内容看看友元类是否真的成功修改成员
}
// 结果为:mLiSi
//        LiSi

很惊讶,我们确实可以通过友元类改掉基类的私有属性,换成是受保护类或者私有方法等结果也是一样的。

5.类指针

类指针和普通的指针类型在声明上并无区别,且其功能也是指向对应实例。但由于继承关系的存在,类指针存在这样的设定,即基类指针除了指向基类实例外,还可以指向子类实例,但是子类指针只能指向子类实例不可以指向基类实例的。附:基类的友元类指针既可以指向友元类实例,也可以指向基类实例,还可以指向子类实例。下面我们还是举一个简单的例子:

class Student
{public:int age=0;string name=" ZhangSan ",uni=" S university ";void show(){cout<<uni<<name<<age<<endl;}
};
class undergraduate:public Student
{public:undergraduate(){name=" LiSi ";}string research="computer";
};
int main()
{// 首先不考虑继承Student* p;Student ZhangSan;p=& ZhangSan;cout<<p->name<<endl;p->show();// 考虑继承undergraduate* p1;undergraduate LiSi;p=&LiSi; // 父类指针指向子类实例p1=&LiSi; // 子类指针指向子类实例// p1=&ZhangSan; // 报错p->show();cout<<p->name<<endl;cout<<p->uni<<endl;// cout<<p->research<<endl; // 虽然父类指针指向了子类实例,但依然不能调用子类特有的属性和方法cout<<p1->name<<p1->research<<endl;
}

需要重点注意的只有一点,那就是虽然基类指针可以指向子类实例,但不可以调用子类的特有成员。
为了方便大家消化,这次就先讲到这里吧,剩下的内容我会放在下一节讲。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/602340.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

G4周:CGAN,手势生成

本文为&#x1f517;365天深度学习训练营 中的学习记录博客 原作者&#xff1a;K同学啊|接辅导、项目定制 我的环境&#xff1a; 1.语言&#xff1a;python3.7 2.编译器&#xff1a;pycharm 3.深度学习框架Pytorch 1.8.0cu111 一、CGAN介绍 条件生成对抗网络&#xff08;…

Crow:路由局部插件1 设置插件

Crow:Middlewares的使用-CSDN博客 介绍了Crow中关于插件的使用,其实除了这种通用插件外,Crow还提供了为个别路由使用的局部插件。 先看例子: //examples/example_middleware.cpp struct SecretContentGuard : crow::ILocalMiddleware {struct context{};void before_hand…

Qt基础-属性系统详解

目录 一、定义 二、属性的使用 三、类的附加信息 四、实例演示 一、定义 Qt提供了一个Q_PROPERTY(

Visio导出eps格式图片

Visio导出eps格式图片 文章目录 Visio导出eps格式图片1. Visio中使用Adobe Acrobat虚拟打印2. Adobe Acrobat中裁剪并另存为eps格式 如何使用Visio绘图然后导出.eps格式的图片呢&#xff1f;这个过程需要用到Adobe Acrobat&#xff0c;使用Adobe Acrobat的虚拟打印功能&#xf…

ssm基于JAVA的驾校信息管理系统设计论文

摘 要 信息数据从传统到当代&#xff0c;是一直在变革当中&#xff0c;突如其来的互联网让传统的信息管理看到了革命性的曙光&#xff0c;因为传统信息管理从时效性&#xff0c;还是安全性&#xff0c;还是可操作性等各个方面来讲&#xff0c;遇到了互联网时代才发现能补上自古…

马克思主义基本原理笔记

马克思主义哲学、政治经济学、科学社会主义理论 哲学 马克思主义中国化的理论成果&#xff1a;毛泽东思想、邓小平理论、三个代表重要思想、科学发展观 物质和意识哪个是本原&#xff0c;是哲学的基本问题 辩证法认为世界上的事物都是相互联系的、运动发展的&#xff0c;形…

Docker:docker exec命令简介

介绍 docker exec [OPTIONS] 容器名称 COMMAND [ARG...] OPTIONS说明&#xff1a; -d&#xff0c;以后台方式执行命令&#xff1b; -e&#xff0c;设置环境变量 -i&#xff0c;交互模式 -t&#xff0c;设置TTY -u&#xff0c;用户名或UID&#xff0c;例如myuser:myu…

Java HashMap 面试题(一)

HashMap 面试题&#xff08;一&#xff09; 文章目录 HashMap 面试题&#xff08;一&#xff09;3.3 面试题-说一下HashMap的实现原理&#xff1f;面试题-HashMap的put方法的具体流程hashMap常见属性源码分析 3.3 面试题-说一下HashMap的实现原理&#xff1f; HashMap的数据结…

篇三:让OAuth2 server支持密码模式

由于Spring-Security-Oauth2停止维护&#xff0c;官方推荐采用 spring-security-oauth2-authorization-server&#xff0c;而后者默认不支持密码授权模式&#xff0c;本篇实战中采用的版本如下&#xff1a; <dependency><groupId>org.springframework.security<…

84. 柱状图中最大的矩形 -- 单调栈

84. 柱状图中最大的矩形 class LargestRectangleArea:"""时间复杂度&#xff1a;O(N)空间复杂度&#xff1a;O(N)84. 柱状图中最大的矩形https://leetcode.cn/problems/largest-rectangle-in-histogram/description/"""def solution(self, heigh…

1-02VS的安装与测试

一、概述 对于一名C语言程序员而言&#xff0c;进行C语言程序的开发一般需要一个文本编辑器加上一个编译器就足够了。但为了方便起见&#xff0c;我们选择使用集成开发环境——Visual Studio&#xff08;简称VS&#xff09;。安装Visual Studio 下面讲一下如何安装VS&#xff0…

【AI视野·今日Sound 声学论文速览 第三十八期】Mon, 1 Jan 2024

AI视野今日CS.Sound 声学论文速览 Mon, 1 Jan 2024 Totally 5 papers &#x1f449;上期速览✈更多精彩请移步主页 Daily Sound Papers The Arrow of Time in Music -- Revisiting the Temporal Structure of Music with Distinguishability and Unique Orientability as the …

金和OA C6 MailTemplates.aspx SQL注入漏洞复现

0x01 产品简介 金和OA协同办公管理系统软件(简称金和OA),本着简单、适用、高效的原则,贴合企事业单位的实际需求,实行通用化、标准化、智能化、人性化的产品设计,充分体现企事业单位规范管理、提高办公效率的核心思想,为用户提供一整套标准的办公自动化解决方案,以帮助…

【DevOps-07-3】Jenkins集成Sonarqube

一、简要说明 Jenkins安装Sonarqube插件Jenkins安装和配置Sonar-Scanner信息Jenkins打包项目中,增加Sonar-Scanner代码质量扫描二、Jenkins安装Sonarqube插件 1、登录Jenkins管理后台,搜索安装Sonar-Scanner插件 Jenkins管理后台示例:http://192.168.95.131:8080/jenkins/

Oracle数据库新手零基础入门,Oracle安装配置和操作使用详解

一、教程描述 本套教程是专门为初学者量身定制的&#xff0c;无需任何Oracle数据库基础&#xff0c;课程采用循序渐进的教学方式&#xff0c;从Oracle数据库的基础知识开始讲起&#xff0c;并不会直接涉及到一项具体的技术&#xff0c;而是随着课程的不断深入&#xff0c;一些…

docker部署mysql主从复制篇

环境准备&#xff1a;docker服务安装&#xff0c;mysql镜像 配置文件方式&#xff1a;可以挂载目录&#xff0c;也可以写好配置文件&#xff0c;利用docker cp 到容器内&#xff0c;这里直接在启动镜像创建容器时候挂载目录方式服务器上配置文件内容(下图标红路径)&#xff1a…

WEB 3D技术 three.js 顶点缩放

本文 我们来说 顶点缩放 我们官网搜索 BufferGeometry 下面有一个 scale 函数 例如 我们先将代码写成这样 上面图片和资源文件 大家需要自己去加一下 import ./style.css import * as THREE from "three"; import { OrbitControls } from "three/examples/j…

Maven的心脏:深入解析settings.xml配置文件

Maven作为Java世界中最著名的构建工具之一&#xff0c;其灵魂所在无疑是那些配置文件。在这些配置文件中&#xff0c;settings.xml扮演着至关重要的角色。今天&#xff0c;我们就来深入剖析这个Maven的心脏部件&#xff0c;看看它如何为我们的项目搏动生命。 一、Maven settin…

分布式事务相关问题及答案(2024)

1、什么是分布式事务&#xff0c;它与单机事务有何区别&#xff1f; 分布式事务是一种跨多个网络分布的计算机节点和资源管理系统的事务。它确保了即便在不同的物理和逻辑分区中&#xff0c;这些操作要么全部成功&#xff0c;要么全部失败&#xff0c;从而保持了事务的原子性。…

常用类型_枚举..

1.自定义类实现枚举效果 现在有这么一个需求&#xff1a; 如果想要表示固定数量的固定值的话 用什么类型比较好 如果从已知的类型来看 仿佛什么类型也不太合适 比如用int类型标识的话 不符合我固定数量的固定值的要求 我们假设用一个类去实现这个需求&#xff1a; 在这个类中提…