C++类和对象——第四关通关

阅读本文章前建议先阅读博主C++专栏的前几篇文文章,以便更好的理解本文章。

目录

(1)构造函数续

初始化列表:

(2)类类型转换:

(3)staic成员

(4)友元

(5)内部类

(6)匿名对象


本文对类和对象的一些边角料知识点进行补充。

(1)构造函数续

前面C++类和对象——第二关-CSDN博客我们已经学习了造函数的一些知识点,这一节我们继续来补充其知识点。

初始化列表:

之前我们都是通过构造函数在函数体初始化成员变量,这里介绍新的初始化方法:初始化列表。

初始化列表:C++没有规定在定义变量(对象)的时候是否要初始化,一般我们没有初始化的话编译器会初始化随机分配一个值,所以每个类成员变量都要走初始化列表,或是我们自己显示实现的,或是编译器实现的。

怎样初始化呢?

当我们创建一个类的时候,其构造函数可以这样初始化成员变量:

构造函数():初始化成员变量1(),初始化成员变量2(),初始化成员变量3(),初始化成员变量4(),……(){构造函数函数体}

具体看一下:

class Time
{
public:Time(int hour = 0, int minute = 2, int second = 0)//初始化列表:每个成员变量初始化定义的地方:_hour(hour = 1),_minute(minute *= 2) //括号里面可以是表达式 ,_second(second){cout << "Time()" << endl;}void print(){cout << _hour << ":" << _minute << ":" << _second << endl;}private:// 成员变量可以添加缺省值int _hour = 1;int _minute = 1;int _second = 1;
};

可能你会想,既然构造函数都可以初始化变量了为什么还需要初始化列表这些东西呢?

当我们在类中定义其他类型的变量的时候:定义引用和const成员变量是必须要初始化的,不然会报错。

class Person
{
public:Person(int age = 1, int height = 2, int weight = 3, double shoesize = 41.5):_age(age = 10),_height(height = 180), _weight(130), _shoesize(shoesize){cout << "Person()" << endl;}void print(){cout << _age << "  " << _height << "  " << _weight << endl;}private:int _age;int _height;double& _shoesize; // 定义引用必须要初始化const int _weight; // 定义const变量必须要初始化
};

那是不是每个变量都要初始化呢?

但我们不初始化前两个值的时候:

#include <iostream>using namespace std;class Person
{
public:Person(int age = 1, int height = 2, int weight = 3, double shoesize = 41.5)//:_age(age = 10)//,_height(height = 180): _weight(130), _shoesize(shoesize){cout << "Person()" << endl;}void print(){cout << "年龄:" << _age << " 身高:" << _height << " 鞋码:" << _shoesize << " 体重:" << _weight << endl;}private:int _age;int _height;double& _shoesize; // 定义引用必须要初始化const int _weight; // 定义const变量必须要初始化
};int main()
{Person p;p.print();return 0;
}

系统会将没有初始化成员变量初始化成随机值。

我们在斜构造函数的时候,会写缺省值,那成员变量是不是也可以写缺省值呢?写了缺省值会怎么样呢?是的C++11支持成员变量加上缺省值。

还是上面的代码,我们将成员变量加上缺省值:

class Person
{
public:Person(int age = 1, int height = 2, int weight = 3, double shoesize = 41.5)//:_age(age = 10)//,_height(height = 180): _weight(130), _shoesize(shoesize){cout << "Person()" << endl;}void print(){cout << "年龄:" << _age << " 身高:" << _height << " 鞋码:" << _shoesize << " 体重:" << _weight << endl;}private:int _age = 12;//加缺省值int _height = 159;//加缺省值double& _shoesize; // 定义引用必须要初始化const int _weight; // 定义const变量必须要初始化
};

由此可见,成员变量是可以加缺省值的,当加上缺省值的时候,如果没有在初始化列表初始化成员变量的化,系统就会使用缺省值初始化成员变量。

在给成员变量缺省值的时候,后面给的也可以是一个表达式:

private:int _age = 12*3;//表达式int _height = 159;double& _shoesize; const int _weight; 
};

那我们写的构造函数的缺省值是干嘛的呢?

答案是:函数的缺省值是构造函数形参的缺省值,成员变量的缺省值,是初始化列表的缺省值。

每个类的成员变量都要走初始化列表,按声明顺序初始化,每个成员只能在初始化列表初始化一次(定义一次)。

跟每个对象都要走构造函数一样的。

总结:

⽆论是否显⽰写初始化列表,每个构造函数都有初始化列表;
⽆论是否在初始化列表显⽰初始化,每个成员变量都要⾛初始化列表初始化;

尽可能的在构造函数里面走初始化列表
 

(2)类类型转换:

定义和声明的区别:是否开空间。

#include <iostream>using namespace std;class B {
public:/*explicit*/ B(int n = 12,int m = 0)// 这里才是定义:_n(n),_m(m){cout << _n << " " << _m << endl;}private:// 这里是声明int _n;int _m;
};int main()
{// 非类类型的类型转换char str = 'A';double x = 12;int y = (int)str; // 显示类型转换,// 类类型的隐式类型转换B b = 12; // 加上exclicit之后就不可以隐式类型转换B d(32); // 显示类型转换return 0;
}

所有的类型转换都是调用拷贝构造产生一个临时对象。

(3)staic成员

static成员函数:

  1. static没有this指针
  2. 只可以访问static成员变量,不可以访问其他变量(因为没有this指针)。但是普通函数可以访问static成员变量

static成员变量:

  1. 不可以有缺省值,不走构造函数初始化列表
  2. 需要在类外面初始化
  3. 和其他static成员变量一样,存在静态区,只不过是受类域限制罢了

code解释:

        

// Static成员
class A {
public:A(int n = 1):_n(n){cout << _n << endl;}// static成员函数不可以访问static成员变量以外的其他成员变量static void Print(){//cout << _n << endl;cout <<_m << endl;}// 普通成员函数可以访问static成员变量void Get(){cout << "_m:" << _m << "_n:" << _n << endl;}//private:int _n;static int _m;
};// static成员函数在类外面初始化
int	A:: _m = 12;int main()
{A a(32);a.Get();return 0;
}

(4)友元

友元函数:使用友元声明就可以访问类的所有成员变量,不受类访问限定符限制

  1. 友元函数声明可以放在类的任意位置,只需要函数前面加上关键字friend
  2. 一个函数可以是多个类的友元。

友元类:声明友元类之后,该类的成员函数就都是另一个类的友元函数

  1. 友元类关系不能传递,如果A是B的友元,B是C的友元,但是A不是C的友元
  2. 友元类的关系是单向的,不具有交换性,⽐如A类是B类的友元,但是B类不是A类的友元。

code解释:

// friend友元函数class B; // 需要前置声明一下B类,因为B类定义在了A类的下面,在A类中访问B类找不到
class A {friend void GetPri(const A& a, const B& b);
public:A(int w = 3, int u = 5):_w(w),_u(u){cout << "A(int w = 3, int u = 5)" << endl;}
private:int _w;int _u;
};class B {friend void GetPri(const A& a, const B& b);friend class A;
public:B(int  n, int m):_n(n), _m(m){cout << "B(int  n, int m)" << endl;}private:int _n;int _m;
};// 一个函数可以是多个类的友元函数
// 友元函数不是成员函数,定义在外面
void GetPri(const A& a, const B& b)
{// 需要实例化对象才能访问对象里面的成员变量cout << b._m << endl;cout << a._u << endl;
}int main()
{B b(1,2);A a;GetPri(a, b);return 0;
}

(5)内部类

字面意思:类里面定义其他类,需要注意的点;

  1. 内部类默认是外部类的友元类
  2. 除了受访问限定符限制之外和其他类一样

code解释:

// 内部类
class A{
private:static int _k;int _h = 1;
public:class B // B默认就是A的友元{public:void foo(const A& a){cout << _k << endl; //OKcout << a._h << endl; //OK}};
};int A::_k = 1;// 内部类使用案例
class Solution {// 内部类class Sum{public :Sum(){_ret += _i;++_i;}};static int _i;static int _ret;
public:int Sum_Solution(int n) {// 变⻓数组Sum arr[n];return _ret;}
};
int Solution::_i = 1;
int Solution::_ret = 0;int main()
{cout << sizeof(A) << endl;A::B b;A aa;b.foo(aa);return 0;
}

(6)匿名对象

  • 生命周期只在当前行,过了当前行就自动调用析构函数销毁了。

code解释:

// 匿名对象
class B {
public:B(int  n, int m):_n(n), _m(m){cout << "B(int  n, int m)" << endl;}private:int _n;int _m;
};int main()
{// 有名对象// 不能这样定义对象:B bb(); 分不清是函数声明还是对象定义B bb(12, 32);//匿名对象B(1, 2);// 生命周期只在当前行,过了当前行就自动调用析构函数销毁了return 0;
}

如果对你有帮助,给个三连支持一下吧!!!!!!!!!!!!!!!!!!!!!!!!!!

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

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

相关文章

在英伟达NIM中测试OCDRNET

OCDRNET结合了OCR和OCD模型的相关内容&#xff0c; 一、OCRNet 模型概述 1.该模型的作用是从灰度图像中识别字符。OCRNet的基础架构是ResNet50&#xff0c;模型版本有&#xff1a; trainable_v1.0 - Pre-trained model with ResNet backbone on scene text.deployable_v1.0 …

使用 three.js和 shader 实现一个五星红旗 飘扬得着色器

使用 three.js和 shader 实现一个五星红旗 飘扬得着色器 源链接&#xff1a;https://threehub.cn/#/codeMirror?navigationThreeJS&classifyshader&idchinaFlag 国内站点预览&#xff1a;http://threehub.cn github地址: https://github.com/z2586300277/three-ce…

centos系列图形化 VNC server配置,及VNC viewer连接,2024年亲测有效

centos系列图形化 VNC server配置&#xff0c;及VNC viewer连接 0.VNC服务介绍 VNC英文全称为Virtual Network Computing&#xff0c;可以位操作系统提供图形接口连接方式&#xff0c;简单的来说就是一款桌面共享应用&#xff0c;类似于qq的远程连接。该服务是基于C/S模型的。…

Ubuntu QT 交叉编译环境搭建

文章目录 下载安装qtCreatornot a valid identifier 的错误 安装g下载并安装交叉编译器下载交叉编译器安装交叉编译器 下载编译 ARM 的Qt平台源码配置arm的QT平台 下载安装qtCreator 去QT下载官网下载对应需要的QT软件。 这里下载5.12.96版本的 改变安装包权限&#xff0c;…

cocos中Sprite的填充模式

做进度条效果会用到Sprite的填充模式: cocoscreator教程&#xff1a;制作进度条_哔哩哔哩_bilibili

对接优惠折扣影票接口有什么好处?

对接电影票接口可以为开发者、商家和用户提供多种好处&#xff0c;以下是一些主要优势&#xff1a; 便捷性&#xff1a;用户可以直接在应用程序或网站上查询电影信息、选择座位和购票&#xff0c;无需离开平台即可完成整个购票流程。 提高用户粘性&#xff1a;为用户提供一站式…

chrome清除https状态

莫名其妙的http跳转到https的url了。 解决办法 浏览器地址栏输入&#xff1a;chrome://net-internals/#hsts 输入你需要删除的域名即可&#xff01;&#xff01;&#xff01;

uni-app 打包成app时 限制web-view大小

今天对接一个uni-app的app 内置对方h5 web-view的形式 需要对方在web-view顶部加点东西 对方打的app的web-view始终是全屏的状态&#xff0c;对方表示做不到我要的效果 emmmmmm。。。。。。 于是乎 自己搭了个demo 本地h5跑起来审查了下代码&#xff0c;发现web-view是给绝对定…

影刀RPA实战:操作Mysql数据库

1.摘要 影刀RPA&#xff08;Robotic Process Automation&#xff09;是一种软件自动化工具&#xff0c;它可以模拟人类用户执行各种重复性任务&#xff0c;其中包括对数据库的操作。 我们可以使用软件自动化指令&#xff0c;通过获取数据库窗口对象来操作数据库&#xff0c;也…

Java项目:157 基于springboot技术的美食烹饪互动平台的设计与实现(含论文+说明文档)

作者主页&#xff1a;源码空间codegym 简介&#xff1a;Java领域优质创作者、Java项目、学习资料、技术互助 文中获取源码 项目介绍 本知识管理系统有管理员和用户两个角色 管理员权限操作的功能包括管理美食&#xff0c;对美食留言进行回复&#xff0c;管理美食知识信息&…

安装和配置k8s可视化UI界面dashboard-1.20.6

安装和配置k8s可视化UI界面dashboard-1.20.6 1.环境规划2.初始化服务器1&#xff09;配置主机名2&#xff09;设置IP为静态IP3&#xff09;关闭selinux4&#xff09;配置主机hosts文件5&#xff09;配置服务器之间免密登录6&#xff09;关闭交换分区swap&#xff0c;提升性能7&…

QT QML 练习8-Simple Transformations

简单的转换&#xff08;Simple Transformations&#xff09; 转换操作改变了一个对象的几何状态。QML元素对象通常能够被平移&#xff0c;旋转&#xff0c;缩放。下面我们将讲解这些简单的操作和一些更高级的用法。 我们先从一个简单的转换开始。用下面的场景作为我们学习的开始…

Qt- QSS风格选择器常用属性选择器样式表盒子

1. 风格设置 Qt 提供了 3 种整体风格&#xff0c;使用 QStyleFactory::keys() 来获取 &#xff08;windowsvista 、Windows 、Fusion&#xff09; 可以在 main.cpp 中调用 setStyle 方法对应用程序进行全局风格的设置 int main(int argc, char *argv[]) {QApplication a(arg…

Redis协议详解及其异步应用

目录 一、Redis Pipeline&#xff08;管道&#xff09;概述优点使用场景工作原理Pipeline 的基本操作步骤C 示例&#xff08;使用 [hiredis](https://github.com/redis/hiredis) 库&#xff09; 二、Redis 事务概述事务的前提事务特征&#xff08;ACID 分析&#xff09;WATCH 命…

爱快路由器配置腾讯云动态域名DDNS详细说明

直白点说就是让爱快路由器自动配置当前公网IP地址给域名&#xff0c;动态域名DDNS不清楚的请自行百度&#xff0c; 这里就可以看见操作日志&#xff0c;那么我们一步一步来配置它吧&#xff0c;首先登录爱快路由器&#xff0c;如下图&#xff1a; 那么腾讯云我们怎么找到ID和…

koa知否论坛交流系统的设计与实现---附源码53933

目 录 1 绪论 1.1研究背景 1.2研究意义 1.3论文结构与章节安排 2 知否论坛交流系统系统分析 2.1 可行性分析 2.1.1 技术可行性分析 2.1.2 经济可行性分析 2.1.3 法律可行性分析 2.2 系统功能分析 2.2.1 功能性分析 2.2.2 非功能性分析 2.3 系统用例分析 2.4本章小…

Spring Boot环境下的大创项目质量保证系统

3系统分析 3.1可行性分析 通过对本大创管理系统实行的目的初步调查和分析&#xff0c;提出可行性方案并对其一一进行论证。我们在这里主要从技术可行性、经济可行性、操作可行性等方面进行分析。 3.1.1技术可行性 本大创管理系统采用SSM框架&#xff0c;JAVA作为开发语言&#…

鸿蒙OS启动流程

启动流程(基于openharmony4.1) 系统上电加载内核后&#xff0c;按照以下流程完成系统各个服务和应用的启动&#xff1a; 内核加载init进程&#xff0c;一般在bootloader启动内核时通过设置内核的cmdline来指定init的位置。init进程启动后&#xff0c;会挂载tmpfs&#xff0c;…

宝塔PHP8.1安装fileinfo拓展失败解决办法

在宝塔面板中安装PHP8.1后&#xff0c;安装fileinfo扩展一直安装不上&#xff0c;查看日志有报错&#xff0c;于是手动来安装也报错。 宝塔报错&#xff1a; 手动命令行编译安装同&#xff0c;也有报错 cd /www/server/php/81/src/ext/fileinfo/ make distclean ./configure …

MongoDB初学者入门教学:与MySQL的对比理解

&#x1f3dd;️ 博主介绍 大家好&#xff0c;我是一个搬砖的农民工&#xff0c;很高兴认识大家 &#x1f60a; ~ &#x1f468;‍&#x1f393; 个人介绍&#xff1a;本人是一名后端Java开发工程师&#xff0c;坐标北京 ~ &#x1f389; 感谢关注 &#x1f4d6; 一起学习 &…