【C++游记】类和对象下——构造函数还有你不知道的细节、静态成员、友元函数、编译器如何优化

【C++游记】类和对象下——构造函数还有你不知道的细节、静态成员、友元函数、编译器如何优化

 

枫の个人主页

你不能改变过去,但你可以改变未来

算法/C++/数据结构/C

Hello,这里是小枫。C语言与数据结构和算法初阶两个板块都更新完毕,我们继续来学习C++的内容呀。C++是接近底层有比较经典的语言,因此学习起来注定枯燥无味,西游记大家都看过吧~,我希望能带着大家一起跨过九九八十一难,降伏各类难题,学会C++,我会尽我所能,以通俗易懂、幽默风趣的方式带给大家形象生动的知识,也希望大家遇到困难不退缩,遇到难题不放弃,学习师徒四人的精神!!!故此得名【C++游记】
 话不多说,让我们一起进入今天的学习吧~~~

1>>再看构造函数

        之前的构造函数还有一点点细节没说,今天咱再对它进行补充。

1.构造函数初始化还有一种方式,就是初始化列表。初始化列表以一个冒号开始,然后是一个个逗号进行分隔的数据成员列表,每个成员变量后跟一个括号中的初始值或者表达式。如_day(5),初始化天数为5。

2.每个成员变量在初始化列表中只能出现一次,也就是唯一性。初始化列表是所有成员变量定义初始化的地方。

3.有三类成员变量(引用、const、无默认构造)必须放在初始化列表进行初始化。

4.C++11支持成员变量在声明的时候给初始值,这个初始值主要是给没在初始化列表的成员变量使用的。

5.简单来说,能用初始化列表就用初始化列表进行初始化工作。

6.初始化列表按照成员变量在类中声明的顺序进行初始化,跟初始化列表顺序无关。

总结: 所有构造函数都有初始化列表。所有成员变量都要走初始化列表进行初始化。

#include<iostream> using namespace std; class D1 { public: D1(int year = 1, int month = 1, int day = 1) :_year(year) , _month(month) , _day(day) { } void print()const { cout << _year << " " << _month << " " << _day << endl; } private: int _year; int _day; int _month; }; int main() { D1 a; a.print(); return 0; }

 

结果为1 1 1 答案正确,这就是初始化列表啦~~

2>>static成员

        降伏了初始化列表,接下来继续打static静态怪吧~
1.用static修饰的成员变量叫静态成员变量,静态成员变量一定要在类外面初始化。为什么?因为之前我们说过类独属一个域,静态成员变量在静态区,所以要在类外面初始化。

2.静态成员变量为所有类对象共享,不属于任何一个具体的对象。

3.静态成员函数没有this指针。

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

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

6.访问静态成员要突破类域,也就是类似于命名空间的类名::静态成员或对象名.静态成员来访问。

7.静态成员受访问限定符限制。

8.静态成员变量不能在声明位置初始化,因为它不属于任何一个对象。
#include<iostream> using namespace std; class D1 { public: D1(int year = 1, int month = 1, int day = 1) :_year(year) , _month(month) , _day(day) { } void print()const { cout << _year << " " << _month << " " << _day << endl; } private: int _year; int _day; int _month; static int person;//需要在类外初始化 }; int D1::person = 1;//初始化记得带上类名 int main() { D1 a; a.print(); return 0; }

3>>友元函数

打完static,又出现了友元怪,小怪好多呀~师傅加把劲!
1.友元是突破类域的一种方式,友元分为:友元函数和友元类。使用方式是在函数声明或者类声明前面加friend,还要把友元的声明放到一个类中。

2.外部友元函数可以访问类的私有和保护成员,它是一个声明,并不是类的成员函数。可以理解为非常好的朋友,你对我干什么都可以。

3.友元可以在类中任意位置定义。

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

5.友元类中的成员函数都可以是另一个类的友元函数。

6.友元类的关系是单向的。我的友元函数是你,意味着你可以随意用我东西,但是我不能随意用你东西。

7.偶尔方便可以使用,但它会增加耦合度,破坏封装。
#include<iostream> using namespace std; class B;//必须有前置声明,否则A都不认识B,vb从上往下执行。 class A { friend void print(const A& aa, const B& bb);//定义aa代替传进来的类变量,bb代替第二个类变量 private: int _a1 = 11; int _a2 = 22; }; class B { friend void print(const A& aa, const B& bb);//定义aa代替传进来的类变量,bb代替第二个类变量 private: int _b1 = 111; int _b2 = 222; }; void print(const A& aa, const B& bb) {//定义aa代替传进来的类变量,bb代替第二个类变量 cout << aa._a1 << endl; cout << bb._b1 << endl; } int main() { A a; B b; print(a, b); return 0; }

#include<iostream> using namespace std; class A { friend class B; private: int _a1 = 11; int _a2 = 22; }; class B { public: void print(const A& aa) {//定义aa代替传进来的类变量,因为A是B的友元,所以B可以访问A的成员变量 cout << aa._a1 << endl; cout << _b1 << endl; } private: int _b1 = 111; int _b2 = 222; }; int main() { A a; B b; b.print(a); return 0; }

4>>编译器的优化

最后的boos战,师傅加把劲!
1.编译器日新月异,在提高版本的过程中进行了一系列的优化,在不影响结果的情况下,会减少部分传参和传值的拷贝构造。

2.编译器的不同会进行不同的优化,连续的拷贝构造会合并成一个拷贝构造。

3.想看具体过程有两个办法,一是在Linux下关闭构造优化,命令为g++ test.cpp -fno-elide-constructors 二是使用较老的编译器,这时候都没有进行更新,也就没有优化的概念。

#include<iostream> using namespace std; class A { public: A(int a = 1) :_a1(a) { cout << "A(int a)" << endl; } A(const A& aa) :_a1(aa._a1)//拷贝构造的初始化列表 { cout << "A(const A& aa)" << endl; } ~A() { cout << "~A()" << endl; } private: int _a1 = 11; }; void f1(A aa) { } int main() { //匿名对象,也就是直接给A赋值,生命周期只有这一行,构造一次,函数内右构造一次还要拷贝一次,然后析构 f1(A(1));//连续的构造加拷贝构造会优化为一个构造 return 0; }

 

 5>>结语

        今日C++到这里就结束啦,如果觉得文章还不错的话,可以三连支持一下。感兴趣的宝子们欢迎持续订阅小枫,小枫在这里谢谢宝子们啦~小枫の主页还有更多生动有趣的文章,欢迎宝子们去点评鸭~C++的学习很陡,时而巨难时而巨简单,希望宝子们和小枫一起坚持下去~你们的三连就是小枫的动力,感谢支持~


 

Read more

OpenClaw:开源AI助手平台的革命之路

OpenClaw:开源AI助手平台的革命之路

OpenClaw:开源AI助手平台的革命之路 引言:AI助手的黎明 2023年,ChatGPT的横空出世让全世界看到了人工智能的无限可能。然而,当我们惊叹于大语言模型(LLM)的强大能力时,一个问题始终萦绕在许多技术爱好者和开发者心头:能否在本地运行属于自己的AI助手? 在这个云服务主导的时代,我们的每一次对话、每一个请求都在云端处理,数据隐私成为一个日益严峻的挑战。而就在这样的背景下,一个名为 OpenClaw 的开源项目悄然崛起,它不仅解决了隐私问题,更开创了个人AI助手的全新范式。 一、什么是OpenClaw? OpenClaw 是一个开源的个人AI助手平台,由开发者 @steipete 创建,采用 MIT 许可证完全免费开放。它的核心理念是:让每个人都能够在自己的电脑上运行AI助手,数据完全掌控在自己手中。 1.1 核心特性 OpenClaw 具备以下颠覆性的特性: * 本地部署:在你的电脑上运行,所有数据处理都在本地完成 * 多平台集成:支持 Discord、Telegram、WhatsApp、iMessage、Slack

By Ne0inhk

GitHub Copilot已过时?2024年这5款AI编码工具正在悄悄颠覆行业

前言 当多数人还在讨论GitHub Copilot时,聪明的开发者早已转向了下一代AI编程工具,它们正在重塑代码生产的边界。 深夜的办公室里,李工刚用一款新的AI工具完成了原本需要三天的工作量。屏幕上闪烁的不是Copilot的提示,而是一个更智能的代码生成界面,它不仅理解了整个项目的架构,甚至预测了接下来的模块需求。 这是2024年的编程现实。当GitHub Copilot凭借先发优势占领市场时,一批更加专业、更深入工作流程的AI编码工具正在悄然崛起。 01 Cursor:IDE的智能进化 如果你还在用VS Code加Copilot插件,Cursor会让你重新思考什么才是“AI原生的开发环境”。 Cursor不是简单的插件增强,而是从底层重构的代码编辑器。它的杀手级功能是: 项目级理解:不只是当前文件,Cursor能理解整个代码库的架构 一键重构:选中代码,输入指令如“添加错误处理并提取为独立模块”,Cursor会精准执行 对话式编程:在编辑器中直接与AI对话,获得代码解释、优化建议 实际案例:张工程师需要将公司一个旧项目的jQuery代码迁移到Vue 3,Cur

By Ne0inhk
【开源】FUXA:HMI-SCADA-Dashboard基于 Web的可视化组态平台

【开源】FUXA:HMI-SCADA-Dashboard基于 Web的可视化组态平台

一、介绍 FUXA 是一款基于 Web 的过程可视化 (SCADA/HMI/Dashboard) 软件。使用FUXA,通过简单的拖放操作,可以迅速创建高度个性化的数据可视化界面。丰富的组态资源、详尽的使用资料、不断完善的模板库、足够开放的设计理念为用户提供灵活、创新、便捷、自由的编程体验。 * 🌐项目地址: https://github.com/frangoteam/FUXA * 🗝️开源协议:MIT License * 🔧技术栈:Node.js(后端) +Angular(前端)+SVG 二、主要特征 * 轻量级和可移植的跨平台应用程序 FUXA 很容易从使用 树莓派、物联网网关等的小型项目扩展到大型设施的可视化。它还提供强大的完全基于 Web 的新工具,允许您实时创建丰富的可视化、数据日志、警报、通知、

By Ne0inhk
GitNexus 核心引擎深度解析

GitNexus 核心引擎深度解析

GitNexus 核心引擎深度解析 索引流水线、社区检测与流程追踪、混合搜索与嵌入生成 一、入口类与架构关系 GitNexus 的核心引擎由三个相互协作的子系统构成:索引流水线(Ingestion Pipeline)、社区与流程检测(Community & Process Detection)、混合搜索与嵌入(Hybrid Search & Embeddings)。这三个子系统共同将原始代码库转换为可查询的知识图谱。 1.1 核心类关系图 1.2 关键数据结构 KnowledgeGraph:知识图谱的核心数据结构,包含节点(Node)和关系(Relationship)集合。节点类型包括 File、Folder、Function、Class、Method、Interface、Community、Process;关系类型包括 CALLS、IMPORTS、EXTENDS、IMPLEMENTS、

By Ne0inhk