C++【类和对象】(再探构造函数、类型转换与static成员)

文章目录

  • 1. 再探构造函数
  • 2. 类型转换
  • 3. static成员
  • 结语

1. 再探构造函数

  • 之前我们实现构造函数时,初始化成员变量主要使用函数体内赋值,构造函数初始化还有⼀种方式,就是初始化列表,初始化列表的使用方式是以⼀个冒号开始,接着是⼀个以逗号分隔的数据成员列表,每个"成员变量"后面跟⼀个放在括号中的初始值或表达式。
#include<iostream>
using namespace std;class A
{
public:A()//初始化列表:a1(1),a2(2){}
private:int a1;int a2;
};
  • 每个成员变量在初始化列表中只能出现一次,语法理解上初始化列表可以认为是每个成员变量定义初始化的地方。

  • 引用成员变量,const成员变量,没有默认构造的类类型变量,必须放在初始化列表位置进行初始化,否则会编译报错。

#include<iostream>
using namespace std;class B
{B(int a){}
};class A
{
public:A()//初始化列表:a1(1),a2(2),// error C2437: “a1”: 已初始化a1(3){}
private:int a1;int a2;//error C2789: “A::a3”: 必须初始化常量限定类型的对象
//error C2530: “A::a4”: 必须初始化引用
//error C2512: “B”: 没有合适的默认构造函数可用const int a3;int& a4;B b1;
};

在这里插入图片描述

  • C++11支持在成员变量声明的位置给缺省值,这个缺省值主要是给没有显示在初始化列表初始化的成员使用的
#include<iostream>
using namespace std;class B
{
public:B(int a){}
};class A
{
public:A()//初始化列表:a1(1),a2(2){}
private:int a1;int a2;//并未在初始化列表const int a3 = 3;int& a4 = a2;B b1 = 1;
};
  • 尽量使用初始化列表初始化,因为那些你不在初始化列表初始化的成员也会走初始化列表如果这个成员在声明位置给了缺省值,初始化列表会用这个缺省值初始化。如果你没有给缺省值,对于没有显示在初始化列表初始化的内置类型成员是否初始化取决于编译器,C++并没有规定。对于没有显示在初始化列表初始化的自定义类型成员会调用这个成员类型的默认构造函数,如果没有默认构造会编译错误。

具体逻辑如下:
在这里插入图片描述
注:

#include<iostream>
using namespace std;class A
{
public:A()初始化列表(定义位置):a1(1),a2(2){}
private:这里是声明位置int a1;int a2;
};
  • 初始化列表中按照成员变量在类中声明顺序进行初始化,跟成员在初始化列表出现的的先后顺序无关。建议声明顺序和初始化列表顺序保持⼀致。

来做一个小题目:

下面程序的运行结果是什么()
A. 输出1 1
B. 输出2 2
C. 编译报错
D. 输出1 随机值
E. 输出1 2
F. 输出2 1

#include<iostream>
using namespace std;class A
{
public:A(int a):_a1(a), _a2(_a1){}void Print() {cout << _a1 <<" "<< _a2 << endl;}
private:int _a2 = 2;int _a1 = 2;
};
int main()
{A aa(1);aa.Print();
}

答案是D(1,随机值),因为成员初始化并不是看初始化列表的顺序,而是看定义的顺序,我们可以看到是 _a2 先定义,所以我们在初始化的时候先初始化 _a2,但由于_a1还没有初始化,这时候还是随机值,所以我们现在是先用随机值来初始化 _a2,然后用形参来初始化 _a1。
在这里插入图片描述

2. 类型转换

class B
{
public:B(int b = 0):_b(b){}private:int _b;
};int main()
{B b1 = 1;return 0;
}

这段代码,又不像赋值运算符重载,又不像拷贝构造的,那么这个是什么呢? 其实这就是一个拷贝构造,但右边明明是一个整数1,为什么是拷贝构造呢,这就涉及到了类型转换的概念了。

  • C++支持内置类型隐式类型转换为类类型对象,需要有相关内置类型为参数的构造函数。

这也就是为什么上面那段代码是拷贝构造了,我们是先把 整形1 转换成了用整形1实例化一个临时的类,然后这个临时类来拷贝构造 b1。

  • 构造函数前⾯加explicit就不再支持隐式类型转换。
    在这里插入图片描述

  • 类类型的对象之间也可以隐式转换,需要相应的构造函数支持。

#include<iostream>
using namespace std;class A
{
public:// 构造函数explicit就不再⽀持隐式类型转换// explicit A(int a1)A(int a1):_a1(a1){}//explicit A(int a1, int a2)A(int a1, int a2):_a1(a1), _a2(a2){}void Print(){cout << _a1 << " " << _a2 << endl;}int Get() const{return _a1 + _a2;}
private:int _a1 = 1;int _a2 = 2;
};
class B
{
public:B(const A& a):_b(a.Get()){}
private:int _b = 0;
};
int main()
{// 1 构造⼀个A的临时对象,再⽤这个临时对象拷⻉构造aa3// 编译器遇到连续构造+拷⻉构造->优化为直接构造A aa1 = 1;aa1.Print();const A& aa2 = 1;// C++11之后才⽀持多参数转化A aa3 = { 2,2 };// aa3隐式类型转换为b对象//原理跟上⾯类似B b = aa3;const B& rb = aa3;return 0;
}

3. static成员

  • 用static修饰的成员变量,称之为静态成员变量,静态成员变量⼀定要在类外进行初始化。

  • 静态成员变量不能在声明位置给缺省值初始化,因为缺省值是个构造函数初始化列表的,静态成员变量不属于某个对象,不走构造函数初始化列表。
    在这里插入图片描述

  • 静态成员变量为所有类对象所共享,不属于某个具体的对象,不存在对象中,存放在静态区。

在这里插入图片描述

  • 用static修饰的成员函数,称之为静态成员函数,静态成员函数没有this指针。
  • 静态成员函数中可以访问其他的静态成员,但是不能访问非静态的,因为没有this指针。
  • 非静态的成员函数,可以访问任意的静态成员变量和静态成员函数。
#include<iostream>
using namespace std;class A
{
public:A(){}static int GetACount(){//rror C2597: 对非静态成员“A::_x”的非法引用_x;return _scount;}void Func(){_scount;GetACount();}
private:// 类⾥⾯声明static int _scount;int _x;
};//类外面初始化
int A::_scount = 0;

在这里插入图片描述

  • 突破类域就可以访问静态成员,可以通过类名::静态成员或者对象.静态成员来访问静态成员变量和静态成员函数。
  • 静态成员也是类的成员,受public、protected、private访问限定符的限制。
    在这里插入图片描述

结语

这次的分享就到这里结束了~
最后感谢您能阅读完此片文章~
如果您认为这篇文章对你有帮助的话,可以用你们的手点一个免费的赞并收藏起来哟~
如果有任何建议或纠正欢迎在评论区留言~
也可以前往我的主页看更多好文哦(点击此处跳转到主页)。

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

如若内容造成侵权/违法违规/事实不符,请联系一条长河网进行投诉反馈,一经查实,立即删除!

相关文章

体系结构论文(五十三):Featherweight Soft Error Resilience for GPUs 【22‘ MIRCO】

Featherweight Soft Error Resilience for GPUs 一、文章介绍 背景&#xff1a;软错误通常由高能粒子&#xff08;如宇宙射线和α粒子&#xff09;打击电路造成的位翻转&#xff0c;可能导致程序崩溃或产生错误输出。随着电子技术的进步&#xff0c;电路对这种辐射引发的软错…

电子连接器温升仿真教程 二

在《电子连接器温升仿真教程 一》中详细介绍了用内热法做电子连接器温升仿真的操作步骤与方法,本教程将讲解用电流电压法做电子连接器温升仿真。 本教程,将以下面产品为例演示温升仿真方法其操作步骤。 该连接器为电池连接器,其Housing材料为LCP+30%GF,端子材质为铍铜…

Linux相关概念和重要知识点(11)(进程调度、Linux内核链表)

1.Linux调度算法 上篇文章我粗略讲过queue[140]的结构&#xff0c;根据哈希表&#xff0c;我们可以将40个不同优先级的进程借助哈希桶链入queue[140]中。调度器会根据queue的下标来进行调度。但这个具体的调度过程是怎样的呢&#xff1f;以及runqueue和queue[140]的关系是什么…

[C++] 剖析AVL树功能的实现原理

文章目录 引言AVL树的关键性质为什么选择AVL树&#xff1f; AVL树的结构节点对象的类 AVL树的插入检查是否为空树并处理根节点查询插入位置&#xff08;非递归&#xff09;插入节点并连接父节点更新平衡因子&#xff08;在失去平衡的条件下进行旋转&#xff09; 旋转旋转的原则…

基于ssm的学生社团管理系统 社团分配系统 社团活动调度平台 学生社团管理 信息化社团管理开发项目 社团活动管理 社团预约系统(源码+文档+定制)

博主介绍&#xff1a; ✌我是阿龙&#xff0c;一名专注于Java技术领域的程序员&#xff0c;全网拥有10W粉丝。作为CSDN特邀作者、博客专家、新星计划导师&#xff0c;我在计算机毕业设计开发方面积累了丰富的经验。同时&#xff0c;我也是掘金、华为云、阿里云、InfoQ等平台…

VMware中Ubuntu系统Docker正常运行但网络不通(已解决)

问题描述&#xff1a;在VMware中的Ubuntu系统下部署了Docker&#xff0c;当在docker容器中运行Eureka微服务时&#xff0c;发现Eureka启动正常&#xff0c;但无法通过网页访问该容器中Eureka。 解决办法如下&#xff1a; 1、创建桥接网络&#xff1a;test-net sudo docker n…

一文带你入门客制化键盘,打造专属打字利器

我用过不少键盘&#xff0c;但是都不太符合自己的需求&#xff0c;最后还是走向了客制化。 客制化&#xff0c;可以理解为自定义、DIY&#xff0c;自己动手拼装出一把只属于自己的键盘。 本文会对客制化做个简单的介绍&#xff0c;旨在读者能自己简单拼装出一款键盘。 目前市…

QStyle文档

前言 本文翻译自Qt官方文档&#xff0c;详细介绍了各成员/类型的作用&#xff0c;包含部分示例代码。 QStyle类的内容非常庞大&#xff0c;如需快速了解类成员和使用简介&#xff0c;请参见 QStyle简介。 一、QStyle Class QStyle是一个抽象基类&#xff0c;封装了GUI的外观…

OpenGL笔记之事件驱动设计将相机控制类和应用程序类分离

OpenGL笔记之事件驱动设计将相机控制类和应用程序类分离 —— 2024-10-02 下午 code review! 文章目录 OpenGL笔记之事件驱动设计将相机控制类和应用程序类分离1.代码图片2.分析3.UML4.代码 1.代码图片 运行 Mouse button 1 pressed at (100, 200) Mouse dragged by (50, 50)…

Spring(学习笔记)

<context:annotation-config/>是 Spring 配置文件中的一个标签&#xff0c;用于开启注解配置功能。这个标签可以让 Spring 容器识别并处理使用注解定义的 bean。例如&#xff0c;可以使用 Autowired 注解自动装配 bean&#xff0c;或者使用 Component 注解将类标记为 bea…

10/02赛后总结

T1学习除法 题目传送门&#xff1a;学习除法http://bbcoj.cn/contest/1028/problem/1 说白了&#xff0c;就是检验是不是质数罢了&#xff0c;是质数输出0&#xff0c;不然输出1&#xff1b; 但是质数判断写错了 100分只有60分&#xff0c;damn #include<bits/stdc.h>…

【Linux】进程间关系与守护进程

超出能力之外的事&#xff0c; 如果永远不去做&#xff0c; 那你就永远无法进步。 --- 乌龟大师 《功夫熊猫》--- 进程间关系与守护进程 1 进程组2 会话3 控制终端4 作业控制5 守护进程 1 进程组 之前我们提到了进程的概念&#xff0c; 其实每一个进程除了有一个进程 ID(P…

Django5 使用pyinstaller打包成 exe服务

首先&#xff1a;确保当前的django项目可以完美运行&#xff0c;再进行后续操作 python manage.py runserver第一步 安装 pyinstaller pip install pyinstaller第二步 创建spec 文件 pyinstaller --name manage --onefile manage.pypyinstaller&#xff1a;这是调用 PyInsta…

数据异质性与数据异构性的本质和举例说明

&#x1f349; CSDN 叶庭云&#xff1a;https://yetingyun.blog.csdn.net/ 在现代数据科学与信息技术领域&#xff0c;“数据异质性” 与 “数据异构性” 是两个常见的概念。对于初学者而言&#xff0c;明确这两个概念的本质及其间的差异至关重要。本文旨在以简明易懂的方式&am…

Python笔记 - 利用装饰器设计注解体系

认识注解 注解&#xff08;Annotation&#xff09;是一种用于为代码添加元数据的机制。这些元数据可以在运行时被访问&#xff0c;用于为代码元素&#xff08;如类、方法、字段等&#xff09;提供额外的信息或指示。 由于Python中装饰器只能装饰类和方法&#xff0c;因此也只…

Mac 网络连接正常,微信可以使用,但浏览器打不开网页?

解决&#xff1a; Step1&#xff0c;选择&#x1f34e;图标&#xff0c;选择系统设置&#xff08;或系统偏好设置&#xff09;打开&#xff1b; Step2&#xff0c;选择网络&#xff0c;Wi-Fi Step3&#xff0c;选择详细信息&#xff1b; Step4: 选择代理&#xff0c;关闭右…

3.点位管理改造-列表查询——帝可得管理系统

目录 前言一、与页面原型差距1.现在&#xff1a;2.目标&#xff1a;3. 存在问题&#xff1a;所在区域和合作商ID展示的都是ID&#xff0c;而不是名称&#xff1b;同时合作商ID应改为合作商 二、修改1.重新设计SQL语句2.修改mapper层&#xff0c;使用Mybatis中的嵌套查询3.修改s…

C. Tree Pruning【Codeforces Round 975 (Div. 1)】

C. Tree Pruning (永远不知道为什么TLE直到把初始化的memset换成for循环 题意很简单&#xff0c;就是找到一个深度&#xff0c;使得删除最少的节点且所有的叶子节点都为这个深度。 从小到大遍历可能的深度i&#xff0c;容易知道所有 深度大于i的节点 和所有 子树最大深度小于i…

操作符详解与表达式求值

目录 操作符分类 1.算数操作符 2.移位操作符&#xff08;只适用于整数范围&#xff09; &#xff08;1&#xff09;引入 &#xff08;2&#xff09;左移操作符<< &#xff08;2&#xff09;右移操作符>> 3.位操作符 4.赋值操作符 复合赋值符 5.单目操作符 5…

深度优先搜索(DFS)与有向图中的唯一结点

深度优先搜索(DFS)与有向图中的唯一结点 前提与定义分析与方法伪代码与 C 代码实现解释结果在图论中,深度优先搜索(DFS)是一种用于遍历或搜索图的算法。DFS 从给定的起始结点出发,沿着图的深度方向尽可能深地搜索,直到无法继续为止,然后回溯并从未访问过的邻接结点继续…