当前位置: 首页 > news >正文

C++初阶——类和对象(下)

目录

1、再探构造函数——初始化列表

2、类型转换

3、static成员

4、友元

5、内部类

6、匿名对象

7、对象拷贝时编译器的优化(了解)


1、再探构造函数——初始化列表

1. 构造函数初始化除了使用函数体内赋值还有一种方式——初始化列表

初始化列表的使用方式是以一个冒号开始,接着是一个以逗号分隔的数据成员列表,每个"成员变量"后面跟一个初始值或表达式

2. 每个成员变量都要走初始化列表,并且在初始化列表中只能出现一次

3. C++11支持在成员变量声明的位置给缺省值,这个缺省值主要是给没有显示在初始化列表初始化的成员使用的

4. C++规定,const成员变量没有默认构造的类类型成员变量必须在初始化列表中 显示初始化或者用缺省值初始化引用成员变量,必须在初始化列表中 显示初始化,否则会编译报错,

由于这三个是定义的时就要求初始化,

所以语法上初始化列表可以认为是每个成员变量定义初始化的地方。

注意:实际上对象在定义时成员变量空间就已经开好了,构造函数只是初始化,不是开空间。

5. 推荐使用初始化列表初始化,因为那些你不在初始化列表初始化的成员变量也会先走初始化列表,

6. 初始化列表按成员变量在类中声明顺序进行初始化,跟成员在初始化列表出现的的先后顺序无关。建议声明顺序和初始化列表顺序保持一致

7. 无论是否显示写初始化列表,每个构造函数都有初始化列表

无论是否在初始化列表显示初始化,每个成员变量都要走初始化列表初始化

#include<iostream>
using namespace std;class Time
{
public:Time(int hour):_hour(hour){cout << "Time()" << endl;}
private:int _hour;
};class Date
{
public:Date(int& x, int year = 1, int month = 1, int day = 1):_year(year), _month(month), _day(day)//, _t(12)//, _ref(x)//, _n(1){// error C2512: “Time”: 没有合适的默认构造函数可用// error C2530 : “Date::_ref” : 必须初始化引用// error C2789 : “Date::_n” : 必须初始化常量限定类型的对象}void Print() const{cout << _year << "-" << _month << "-" << _day << endl;}
private:int _year;int _month;int _day;Time _t;       // 没有默认构造的类类型成员变量int& _ref;          // 引用成员变量const int _n;   // const成员变量
};int main()
{int i = 0;Date d1(i);d1.Print();return 0;
}
#include<iostream>
using namespace std;class Time
{
public:Time(int hour):_hour(hour){cout << "Time()" << endl;}
private:int _hour;
};class Date
{
public:Date():_month(2){cout << "Date()" << endl;}void Print() const{cout << _year << "-" << _month << "-" << _day << endl;}
private:// 注意这里不是初始化,这里给的是缺省值,这个缺省值是给初始化列表用的// 如果初始化列表没有显示初始化,默认就会用这个缺省值初始化int _year = 1;int _month = 1;int _day;Time _t = 1;const int _n = 1;int* _ptr = (int*)malloc(12);
};
int main()
{Date d1;d1.Print();return 0;
}

#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   随机值,  初始化列表按成员变量声明顺序初始化

2、类型转换

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

2. 构造函数前加explicit不再支持隐式类型转换

3. 类类型的对象之间也可以隐式转换,需要有相应的构造函数

#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的临时对象,再用这个临时对象拷贝构造aa1// 编译器遇到连续构造+拷贝构造->优化为直接构造A aa1 = 1;aa1.Print();// aa2是临时对象的别名,此时临时对象的生命周期也随之改变const A& aa2 = 1;// C++11之后才支持多参数转化A aa3 = { 2,2 };// aa3隐式类型转换为b对象// 原理跟上面类似B b = aa3;const B& rb = aa3;return 0;
}

3、static成员

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

2. 静态成员变量属于类而不是属于类的对象的共享数据,不存在对象中,存放在静态区

3. 用static修饰的成员函数,称之为静态成员函数属于类,而不是对象

4. 静态成员函数中可以访问其他的静态成员,但是不能访问非静态的,因为没有this指针。

5.非静态的成员函数可以访问任意的静态成员变量和静态成员函数

6. 在类外,可以通过类名::静态成员或者对象.静态成员来访问静态成员变量和静态成员函数。

7. 静态成员也是类的成员,受public、protected、private访问限定符的限制

8. 静态成员变量不能声明位置给缺省值初始化,因为静态成员变量不属于某个对象不走构造函数初始化列表

// 实现⼀个类,计算程序中创建出了多少个类对象?
#include<iostream>
using namespace std;
class A
{
public:A(){++_scount;}A(const A& t){++_scount;}~A(){--_scount;}static int GetACount(){return _scount;}
private:// 类里面声明static int _scount;
};
// 类外面初始化
int A::_scount = 0;int main()
{cout << A::GetACount() << endl; // 0A a1, a2;A a3(a1);cout << A::GetACount() << endl; // 3cout << a1.GetACount() << endl; // 3// 编译报错:error C2248 : “A::_scount” :无法访问private成员(在“A”类中声明)//cout << A::_scount << endl;return 0;
}

求1+2+3+...+n_牛客题霸_牛客网

class Sum
{
public:Sum(){_sum += _i;++_i;}static int GetSum(){return _sum;}
private:static int _i;static int _sum;
};int Sum::_i = 1;
int Sum::_sum = 0;class Solution {public:int Sum_Solution(int n) {Sum a[n];return Sum::GetSum();}
};

4、友元

1. 友元提供了一种突破类访问限定符封装的方式,

友元分为:友元函数友元类

函数声明或者类声明加friend,并将其放到一个类中

2. 外部友元函数可访问类的私有保护成员,友元函数仅仅是一种声明,不是类的成员函数

3. 友元函数可以在类定义的任何地方声明不受类访问限定符限制

4. 一个函数可以是多个类的友元函数

5. 友元类中的成员函数都可以是另一个类友元函数,都可以访问另一个类中的私有保护成员

6. 友元类的关系单向的,不具有交换性,比如A类是B类的友元,但是B类不是A类的友元。

7. 友元类关系不能传递,如果A是B的友元,B是C的友元,但是A不是C的友元。

8. 有时提供了便利。但是友元会增加耦合度,破坏了封装,所以友元不宜多用

#include<iostream>
using namespace std;// 前置声明,否则A的友元函数声明编译器不认识B
class B;class A
{// 友元声明friend void func(const A& aa, const B& bb);
private:int _a1 = 1;
};class B
{// 友元声明friend void func(const A& aa, const B& bb);
private:int _b1 = 3;
};void func(const A& aa, const B& bb)
{cout << aa._a1 << endl; //  1cout << bb._b1 << endl; //  3
}int main()
{A aa;B bb;func(aa, bb);return 0;
}
#include<iostream>
using namespace std;class A
{// 友元声明friend class B;
private:void F() const{cout << "F" << endl;}int _a1 = 1;
};class B
{
public:void func1(const A& aa){cout << aa._a1 << endl; // 1aa.F(); // Fcout << _b1 << endl; // 3}
private:int _b1 = 3;
};int main()
{A aa;B bb;bb.func1(aa);return 0;
}

5、内部类

1. 如果一个类定义在另一个类的内部,这个内部的类就叫做内部类

内部类是一个独立的类,跟定义在全局相比,他受外部类类域限制访问限定符限制,所以外部类定义的对象中不包含内部类

2. 内部类默认是外部类的友元类,可以访问私有保护成员外部类无法访问内部类的私有成员

3. 内部类本质也是一种封装,当A类跟B类紧密关联,A类实现出来主要就是给B类使用,那么可以考虑把A类设计为B的内部类,如果放到private/protected位置,那么A类就是B类的专属内部类,其 他地方都用不了。

#include<iostream>
using namespace std;class A
{
public:class B // B默认就是A的友元{public:void foo(const A& a){cout << _k << endl;          // 1 OKcout << a._h << endl;        // 1 OK}};
private:static int _k;int _h = 1;
};int A::_k = 1;int main()
{// sizeof是当创建这个类型的一个对象(或变量)的时候,需要为它分配的空间的大小// sizeof会忽略static成员变量的大小cout << sizeof(A) << endl; // 4,A::B b;A aa;b.foo(aa);return 0;
}

求1+2+3+...+n_牛客题霸_牛客网

class Solution {
// 私有的内部类,专属
private:class Sum {public:Sum() {_sum += _i;++_i;}};
public:int Sum_Solution(int n) {Sum a[n];return _sum;}
private:static int _i;static int _sum;
};int Solution::_i = 1;
int Solution::_sum = 0;

6、匿名对象

1. 用类型(实参)定义出来的对象叫做匿名对象,相比之前我们定义的类型对象名(实参)定义出来的 叫有名对象。

2. 匿名对象生命周期只在当前一行,一般临时定义一个对象当前用一下的话,就可以定义匿名对象。

#include<iostream>
using namespace std;class A
{
public:A(int a = 0):_a(a){cout << "A(int a)" << endl;}~A(){cout << "~A()" << endl;}
private:int _a;
};class Solution {
public:int Sum_Solution(int n) {//...return n;}
};int main()
{A aa1;// 不能这么定义对象,因为编译器无法识别是⼀个函数声明,还是对象定义//A aa1();// 但是我们可以这么定义匿名对象,匿名对象的特点不用取名字,// 但是他的生命周期只有这一行,我们可以看到下一行他就会自动调用析构函数A();A(1);A aa2(2);// 匿名对象在这样场景下就很好用,当然还有一些其他使用场景,这个我们以后遇到了再说// 匿名对象Solution()Solution().Sum_Solution(10);return 0;
}

7、对象拷贝时编译器的优化(了解)

1. 现代编译器会为了尽可能提高程序的效率,在不影响正确性的情况下尽可能减少一些传参和传返回值的过程中可以省略的拷贝

2. 如何优化C++标准并没有严格规定,各个编译器会根据情况自行处理。当前主流的相对新一点的编译器对于连续一个表达式步骤中的连续拷贝会进行合并优化,有些更新更"激进"的编译器还会进行跨行跨表达式的合并优化。

相关文章:

C++初阶——类和对象(下)

目录 1、再探构造函数——初始化列表 2、类型转换 3、static成员 4、友元 5、内部类 6、匿名对象 7、对象拷贝时编译器的优化(了解) 1、再探构造函数——初始化列表 1. 构造函数初始化除了使用函数体内赋值&#xff0c;还有一种方式——初始化列表&#xff0c; 初始化列…...

趋势洞察|AI 能否带动裸金属 K8s 强势崛起?

随着容器技术的不断成熟&#xff0c;不少企业在开展私有化容器平台建设时&#xff0c;首要考虑的问题就是容器的部署环境——是采用虚拟机还是物理机运行容器&#xff1f;在往期“虚拟化 vs. 裸金属*”系列文章中&#xff0c;我们分别对比了容器部署在虚拟化平台和物理机上的架…...

idea初始化设置

下载idea&#xff1a; https://www.jetbrains.com/idea/ 安装idea 安装插件&#xff1a; Rainbow BracketsLombokMybatisXSonarLintMaven HelperCodeGeeX&#xff08;国内AI插件可用&#xff09; 设置idea注释模板&#xff1a; 设置代码注释模板&#xff1a; https://blo…...

LINUX系统编程之——环境变量

目录 环境变量 1、基本概念 2、查看环境变量的方法 三、查看PATH环境变量的內容 1&#xff09;不带路径也能运行的自己的程序 a、将自己的程序直接添加到PATH指定的路径下 b、将程序所在的路径添加到PATH环境中 四、环境变量与本地变量 1、本地变量创建 2、环境变量创…...

健康老龄化:适合老年人的播客

什么是播客 什么是播客&#xff1f;好问题。对于那些还不熟悉这个术语的人来说&#xff0c;播客有点像在线广播或电视节目。这是一个可下载、可流式传输的程序&#xff0c;定期发布剧集&#xff0c;时长从几分钟到一个多小时不等。您可以在计算机、智能手机或平板电脑上…...

家庭智慧工程师:如何通过科技提升家居生活质量

在今天的数字化时代&#xff0c;家居生活已经不再只是简单的“住”的地方。随着物联网&#xff08;IoT&#xff09;、人工智能&#xff08;AI&#xff09;以及自动化技术的快速发展&#xff0c;越来越多的家庭开始拥抱智慧家居技术&#xff0c;将他们的家变得更加智能化、便捷和…...

Milvus概念

非结构化数据、嵌入和 Milvus 非结构化数据&#xff08;如文本、图像、音频&#xff09;格式多样&#xff0c;蕴含丰富的语义信息&#xff0c;使其分析变得复杂。为了管理这种复杂性&#xff0c;嵌入技术被用来将非结构化数据转换为数值向量&#xff0c;这些向量能够捕捉数据的…...

为什么调用 setState 而不是直接改变 state

在React中&#xff0c;调用setState方法而不是直接改变state的原因涉及多个方面&#xff0c;包括性能优化、状态管理的可预测性、React的设计理念等。以下是对这些原因的详细解释&#xff1a; 1. 性能优化 异步更新与批量处理&#xff1a;setState是异步执行的&#xff0c;Rea…...

【Python爬虫五十个小案例】爬取豆瓣电影Top250

博客主页&#xff1a;小馒头学python 本文专栏: Python爬虫五十个小案例 专栏简介&#xff1a;分享五十个Python爬虫小案例 &#x1fab2;前言 在这篇博客中&#xff0c;我们将学习如何使用Python爬取豆瓣电影Top250的数据。我们将使用requests库来发送HTTP请求&#xff0c;…...

cocos creator 3.8 物理碰撞器Collider+刚体RigidBody 8

遇到一个朋友&#xff0c;你来就行的朋友&#xff0c;我过去了&#xff0c;管吃管住&#xff0c;这样的朋友真的很难求。 最近离职了&#xff0c;很难想象&#xff0c;一份策划书一天能给你改n次&#xff0c;一周能郁闷&#xff0c;上一个功能没搞完&#xff0c;让你搞下一个功…...

Python爬取豆瓣电影全部分类数据并存入数据库

在当今数字化的时代&#xff0c;网络上丰富的影视资源信息吸引着众多开发者去挖掘和利用。今天&#xff0c;我就来和大家分享一段有趣的代码&#xff0c;它能够从豆瓣电影平台获取相关数据并存储到数据库中哦。 结果展示&#xff08;文末附完整代码&#xff09;&#xff1a; 目…...

算法模板1:排序+二分+高精度+前缀+差分

文章目录 1.1 排序STL sort函数快速排序算法模板归并排序算法模板 1.2 二分整数二分算法模板浮点数二分算法模板 1.3 高精度高精度加法高精度减法高精度乘低精度高精度除以低精度 1.4 前缀和与差分**一维前缀和****二维前缀和****一维差分****二维差分** 之前整理了好多算法模板…...

SpringBoot实现单文件上传

一、在springBoot项目中的pom.xml添加依赖。 <dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-web</artifactId></dependency> 二、在资源目录下的static目录下中创建一个upload.html的表单文件…...

rust中解决DPI-1047: Cannot locate a 64-bit Oracle Client library问题

我们在使用rust-oracle crate连接oracle进行测试的过程中&#xff0c;会发现无法连接oracle&#xff0c;测试运行过程中抛出“DPI-1047: Cannot locate a 64-bit Oracle Client library”错误。该问题是由于rust-oracle需要用到oracle的动态连接库&#xff0c;我们通过安装orac…...

YOLOv11(Ultralytics)视频选定区域目标统计计数及跟踪

在计算机视觉的众多应用场景中&#xff0c;对特定区域的目标进行检测、跟踪与计数是一个常见且重要的需求。无论是在智慧交通中统计通过特定路口的车辆数量&#xff0c;还是在零售分析中追踪进入特定区域的顾客行为&#xff0c;这一功能都发挥着不可或缺的作用。 随着深度学习…...

24小时自动监控,自动录制直播蓝光视频!支持抖音等热门直播软件

文章目录 📖 介绍 📖🏡 演示环境 🏡📒 工具特点📒📝 使用🎈 获取方式 🎈⚓️ 相关链接 ⚓️📖 介绍 📖 对于许多直播爱好者和内容创作者而言,错过心爱的直播或难以搜集视频素材始终是一个难题。今天,给大家分享的这款工具可以轻松解决这个问题,它拥有…...

InfiniBand(IB)快速上手

什么是IB&#xff1a; InfiniBand&#xff08;直译为“无限带宽”技术&#xff0c;缩写为IB&#xff09;是一个用于高性能计算的计算机网络通信标准&#xff0c;它具有极高的吞吐量和极低的延迟&#xff0c;用于计算机与计算机之间的数据互连。InfiniBand也用作服务器与存储系…...

D74【 python 接口自动化学习】- python 基础之HTTP

day74 http基础定义 学习日期&#xff1a;20241120 学习目标&#xff1a;http定义及实战 -- http基础介绍 学习笔记&#xff1a; HTTP定义 HTTP 是一个协议&#xff08;服务器传输超文本到浏览器的传送协议&#xff09;&#xff0c;是基于 TCP/IP 通信协议来传递数据&…...

移动光猫[HS8545M5-10]获取超密

移动光猫[HS8545M5-10]获取超级密码 1、缘由2、前期准备2.1、确保本地开通telnet客户端功能2.2、准备好相关软件 3、开始查找超密 1、缘由 最近想折腾一下ipv6ddns打通内外网&#xff0c;查询资料说是需要将光猫桥接到外网&#xff1b;但是使用光猫后边的用户名密码根本就找不到…...

原生JS和CSS,HTML实现开屏弹窗

开屏弹窗常应用于打开游戏&#xff0c;或者打开网站的时候&#xff0c;跳出来在正中间&#xff0c;来显示一些信息&#xff0c;并可以设置今日不再显示 CSS代码如下 <style>#box {width: 100vw;height: 100vh;background-color: rgba(0, 0, 0, 0.2);position: relative…...

终极指南:如何用novel-downloader小说下载器批量保存网络小说

终极指南&#xff1a;如何用novel-downloader小说下载器批量保存网络小说 【免费下载链接】novel-downloader 一个可扩展的通用型小说下载器。 项目地址: https://gitcode.com/gh_mirrors/no/novel-downloader 你是否曾遇到过这种情况&#xff1a;熬夜追更的小说突然从网…...

深入掌握Android响应式编程:RxJava与Kotlin Coroutines+Flow实战指南

目录 响应式编程范式解析 RxJava核心架构剖析 操作符系统深度应用 多线程调度实战策略 Kotlin协程基础重构 Flow异步流处理机制 StateFlow与SharedFlow应用场景 响应式测试方法论 复杂状态管理实战 性能优化与异常处理 技术选型对比指南 面试题库精粹 第一章 响应式编程范式解析…...

【DeepSeek敏感信息过滤实战指南】:20年安全专家亲授5大误判陷阱与99.97%准确率调优公式

更多请点击&#xff1a; https://codechina.net 第一章&#xff1a;DeepSeek敏感信息过滤的核心原理与演进脉络 DeepSeek敏感信息过滤系统并非依赖单一规则引擎或静态词库&#xff0c;而是融合多层级语义理解、上下文感知建模与动态策略调度的复合型防护架构。其核心原理建立在…...

Legacy iOS Kit:让旧款iPhone/iPad重获新生的终极指南

Legacy iOS Kit&#xff1a;让旧款iPhone/iPad重获新生的终极指南 【免费下载链接】Legacy-iOS-Kit An all-in-one tool to restore/downgrade, save SHSH blobs, jailbreak legacy iOS devices, and more 项目地址: https://gitcode.com/gh_mirrors/le/Legacy-iOS-Kit …...

分布式接口幂等性设计:唯一索引、Token 与分布式锁

接口幂等性解决的是“同一个请求被执行多次&#xff0c;会不会造成重复业务效果”的问题。用户重复点击、网络重试、MQ 重复消费&#xff0c;都可能让同一业务被重复执行。 一句话概括&#xff1a;幂等就是多次调用和一次调用的业务结果一致&#xff1b;查询和按唯一值删除天然…...

体验Taotoken多模型路由能力在不同负载下的稳定性表现

&#x1f680; 告别海外账号与网络限制&#xff01;稳定直连全球优质大模型&#xff0c;限时半价接入中。 &#x1f449; 点击领取海量免费额度 体验Taotoken多模型路由能力在不同负载下的稳定性表现 在将大模型能力集成到实际业务时&#xff0c;服务的稳定性与响应速度是开发…...

Wonder3D:如何用一张照片在3分钟内创建专业3D模型?

Wonder3D&#xff1a;如何用一张照片在3分钟内创建专业3D模型&#xff1f; 【免费下载链接】Wonder3D Single Image to 3D using Cross-Domain Diffusion for 3D Generation 项目地址: https://gitcode.com/gh_mirrors/wo/Wonder3D 你是否曾想过将一张普通的2D照片变成可…...

2026年5款AI声音克隆工具对比实测,短音频素材如何免训练生成口播声?

短视频团队卡在声音克隆这一步很多做矩阵账号的运营同学反馈&#xff1a;手头只有主播15秒的口播片段&#xff0c;想批量生成不同脚本的配音口播&#xff0c;但主流工具要么要求3分钟以上音频、要么克隆后口型错位、要么导出后还得手动配到视频里——整个链路断在‘声’上。更棘…...

GNSS欺骗干扰检测算法与实验验证方法【附仿真】

✨ 长期致力于GNSS欺骗干扰检测、信号检测、伪距差分、捷联惯性导航、IMU信号生成、四元数、对偶四元数、惯性辅助、单星紧组合、欺骗干扰场景模拟研究工作&#xff0c;擅长数据搜集与处理、建模仿真、程序编写、仿真设计。 ✅ 专业定制毕设、代码 ✅ 如需沟通交流&#xff0c;…...

VisualGGPK2终极指南:轻松管理《流放之路》游戏资源的完整教程

VisualGGPK2终极指南&#xff1a;轻松管理《流放之路》游戏资源的完整教程 【免费下载链接】VisualGGPK2 Library for Content.ggpk of PathOfExile (Rewrite of libggpk) 项目地址: https://gitcode.com/gh_mirrors/vi/VisualGGPK2 VisualGGPK2是一款专为《流放之路》(…...