C++编程法则
文章平均质量分 70
细说C++编程法则
奇妙之二进制
csdn博客专家,C/C++领域优质创作者,抖音搜奇妙之二进制,专注于Linux C/C++、嵌入式Linux开发,偶尔谈谈人生,目前致力于完成大约500篇的linux C/C++开发知识体系库,所有的文章都会一直保持更新(优化内容、排版),想学习的可以订阅我的专栏,也可以关注Linux 世界。
展开
-
C++编程法则365天一天一条(0)了解C++的发展历史
C++ 语言是从C语言发展而来的。C语言有很多优点,也有很多不足。如对类型匹配的检查不够严格、基本没有支持代码重用的机制、不支持面向对象等。这使得在用C语言开发大规模的软件时,维护和扩充都比较困难。20世纪70年代中期,Bjarne Stroustrup在剑桥大学计算机中心工作。他使用过Simula和ALGOL,接触过C。他对Simula的类体系感受颇深,对ALGOL的结构也很有研究,深知运行效率的意义。既要编程简单、正确可靠,又要运行高效、可移植,是Bjarne Stroustrup的初衷。以C为背景原创 2021-01-03 00:00:41 · 906 阅读 · 1 评论 -
C++编程法则365天一天一条(1)关于main函数你了解多少
简单来说,return 语句让程序从main() 函数中正常离开,并返回一个整型值作为程序的退出状态,同时会执行自动对象的析构函数。如果通过 std::exit 函数退出程序,则会立即停止程序的运行并退出。在执行 main() 函数中的 return 语句(或者在主函数结束时隐式返回)时,相当于正常离开该函数,并且会销毁所有自动存储期的对象,然后将return 语句的返回值传递给 std::exit调用。main() 函数是C/C++程序的入口函数,整个程序从此处开始执行。main函数不能当普通函数调用。原创 2023-05-21 01:37:53 · 516 阅读 · 0 评论 -
C++编程法则365天一天一条(2)goto语句的一些坑
从自动变量的作用域退出(即跨越了自动变量的声明所在位置),比如从某个语句块的内部向外跳出,或者从一个函数的任何位置返回时,那么程序会按照它们创建时相反的顺序调用所有已定义析构函数的自动变量进行销毁操作。换句话说,C++编译器将按照变量定义的相反顺序调用自动变量的析构函数,以保证在变量结束其生命周期之前能够完成它们所需的清理工作(比如释放分配的内存等)。需要注意的是,上述规定仅适用于自动变量,在栈中分配内存的对象,对于静态变量或全局变量来说则不适用。换句话说,如果要从一个变量声明(例如、原创 2023-05-21 13:14:23 · 593 阅读 · 0 评论 -
C++编程法则365天一天一条(3)探索浮点数的存储方式
指数位(8 bits或11 bits):指数是以二进制补码方式存储的带符号整数值。对于单精度浮点数,小数位占用23个bits,最高位始终为1(因此可以被省略),其余22位则表示小数部分;对于双精度浮点数,小数位占用52个bits,最高位也是1,其余51位则表示小数部分。对于特殊值,其指数位全部置为1,而小数位全为0或一部分为0一部分为1。小数转二进制和整数转二进制一样,只不过每一位的权重从2的n次方变成2的-n次方。符号位(1 bit):规定为0表示正数,1表示负数。0.25:为2^-2,即为0.01。原创 2023-05-21 15:13:52 · 559 阅读 · 0 评论 -
C++编程法则365天一天一条(4) 什么是平凡类型(Trivial types)?
虽然这是C++的基本概念,但是很多人都不懂,也没有关注过,所以列为C++高阶内容。trivial意思是不重要的,trivial类型的直观表现是,它占据一片连续的内存,就像内建类型或者C的结构体类型、联合体类型一样,但它可以是class或者struct,它的成员可以有访问修饰符控制,这样的类型我们可以直接拷贝到char或者unsigned char数组,然后再拷贝回来,它仍然是原本的类型,换句话就是它可以序列化和反序列化为二进制。满足以下三个条件,该类型就是trivial类型:有默认构造、析构、拷贝构原创 2021-03-31 09:56:27 · 4235 阅读 · 1 评论 -
C++编程法则365天一天一条(5)引用全部知识点
文章目录1、引用2、引用和指针的区别3、引用的作用4、常引用1、引用引用就是某一变量(目标)的一个别名,对引用的操作与对变量直接操作完全一样。引用的声明方法:类型标识符 &引用名=目标变量名; int a; int &ra=a; //定义引用ra,它是变量a的引用,即别名说明:(1)&在此不是求地址运算,而是起标识作用。(2)类型标识符是指目标变量的类型。注意事项:(1)声明引用时,必须同时对其进行初始化。(2)引用声明完毕后,相当于目标变量原创 2020-11-30 23:39:47 · 694 阅读 · 1 评论 -
C++编程法则365天一天一条(6)转换构造函数
💂关于作者: 曾就职于国内知名安防上市公司,现就职于国内知名AMR机器人公司,担任高级系统软件工程师。2020年至今保持CSDN博客专家,CSDN C/C++领域优质创作者头衔。多年过去,历经变迁,物是人非。然而,对于技术的探索和追求从未停歇。💪坚持创作,热衷分享,初心未改,继往开来!参考:https://en.cppreference.com/w/cpp/language/converting_constructor。👀 作者简介: 热衷于知识探索和分享的技术博主。💂 csdn主页::【原创 2023-03-12 20:54:44 · 142 阅读 · 0 评论 -
C++编程法则365天一天一条(7)static_cast强制类型转换用法剖析
static_cast是一个强制类型转换操作符。强制类型转换,也称为显式转换,C++中强制类型转换操作符有static_cast、dynamic_cast、const_cast、reinterpert_cast四个。本节介绍static_cast操作符。其使用方法如下:target-type为目标类型,即static_cast返回的类型,由用户指定。只有以下转换可以使用static_cast:static_cast操作符用于执行向下转换(downcast)。在指定条件下,当目标类型(target-type原创 2023-08-22 23:45:52 · 871 阅读 · 0 评论 -
C++编程法则365天一天一条(8)const_cast去除cv限定
const_cast主要用于去除cv限定,且在C++提供的4个类型转换运算符里,只有const_cast可以去除cv属性。请注意,使用const_cast需要谨慎,并且在正确的情况下使用。滥用const_cast可能导致未定义的行为或逻辑错误。num 的值还是5,并没有修改成1。原创 2023-08-25 23:04:43 · 209 阅读 · 0 评论 -
C++编程法则365天一天一条(9)static_assert静态断言
如果 T 是一个非整型类型,则在编译时会产生一条错误消息。这样,在使用 MyClass 时,就能够在编译期检查出非法的类型参数,避免在运行时出现异常。例如,在定义模板类或模板函数时,可以使用 static_assert 对传入的模板参数进行检查,确保其满足某个约束条件,避免出现编译错误。值得一提的是,std提供了很多模板函数,结合static_assert我们可以实现很多编译期的断言,将风险扼杀于摇篮之中。代码静态检查:通过在编译时进行静态断言,可以在开发过程中尽早地发现代码中的问题,避免运行时出现异常。原创 2023-04-16 13:18:01 · 562 阅读 · 0 评论 -
C++编程法则365天一天一条(10)关于this指针的秘密
1)this指针属于类的一部分,在对象创建的时候this指针才出现,而不是在类声明的时候。2)this指针不是类的成员,是类成员函数的隐含的第一个参数,意思就是,每个类成员函数都传递进去了this指针。3)this指针的作用域只在当前这个类中,同时this指针只能在类成员函数中使用,在函数外部使用是非法的,这也是因为this指针是函数的第一个隐含形参。4)this指针可以指向类中任意的成员,包括变量和函数。实际上我们在成员函数内部访问成员变量时,即使通过this指针访问的,只不过我们没有显示的写出th原创 2020-11-30 00:07:34 · 4245 阅读 · 1 评论 -
C++编程法则365天一天一条(11)reinterpret_cast重新解释类型
需要注意的是,reinterpret_cast 的使用应该非常有限,并且应该慎重评估程序中的替代方案。它通常用于特定的低级操作或与 C 代码进行交互时,但在大多数情况下,最好使用更安全和语义明确的转换操作符,如 static_cast 或 dynamic_cast。在上述示例中,我们将 int 类型的指针转换为 char* 类型的指针,这是合法的,因为指针之间的位模式可能不会改变。因此,使用 reinterpret_cast 应该谨慎且明智,只在确保类型转换是可行并且不会导致未定义行为的情况下使用。原创 2021-05-10 00:49:34 · 538 阅读 · 0 评论 -
C++编程法则365条一天一条(13)认识各种初始化术语
第三点是我们熟悉的,如果提供的字符串的长度小于数组大小,那么数组的剩余元素会被初始化为0。原创 2023-04-10 01:23:22 · 490 阅读 · 0 评论 -
C++编程法则365天一天一条(14)sizeof运算符使用
这是因为在内存中分配空间时,为了确保不同的对象具有唯一的地址,每个对象都需要占用至少一个字节的空间。不完全类型(incomplete types):如果一个类型是不完全的,即它的定义尚未完全提供(如只有声明但没有定义),那么。例如,当我们分配内存或操作具有特定大小要求的数据结构时,了解对象的大小非常重要。引用类型是对某种类型的别名或引用,它们并不占据额外的存储空间,因此与原始类型相比,它们的大小是相同的。的结果将始终是1(除非特定的编译器定义了不同的对齐规则)。运算符的结果是引用类型所指的类型的大小。原创 2023-09-24 21:57:50 · 194 阅读 · 0 评论 -
C++编程法则365天一天一条(15)C++异常如何写
您可以通过继承和重载exception类来定义新的异常。原创 2022-10-20 20:03:06 · 609 阅读 · 0 评论 -
C++编程法则365天一天一条(16)空{}初始化讨论,A a{};表示什么意思?
👀 作者简介: 热衷于知识探索和分享的技术博主。💂 csdn主页::【✍️ 微信公众号:【🎉精彩专栏:💪 【🎓 【 🧡 【 📚 【 🌎 【✍️ 【🤩 【😉 【🥰 【🔥 【✨ 【🎉 【🤔 【✔️ 【🚀 【😊 【 …💂关于作者: 曾就职于国内知名安防上市公司,现就职于国内知名AMR机器人公司,担任高级系统软件工程师。2020年至今保持CSDN博客专家,CSDN C/C++领域优质创作者头衔。全网5万+粉丝。十载寒冰,难凉热血;原创 2023-03-13 00:03:02 · 238 阅读 · 0 评论 -
C++编程法则365天一天一条(17)成员初始化器和成员初始化器列表
构造函数初始化列表以一个冒号开始,接着是以逗号分隔的数据成员列表,每个数据成员后面跟一个放在括号中的初始化式。例如:class A {public: int a_; float b_; A(int a,float b): a_(a),b_(b) {} //构造函数初始化列表};class A {public: int a_; float b_; A(int a,float b) {//构造函数内部赋值 a_ = a;原创 2020-11-29 23:57:57 · 2067 阅读 · 0 评论 -
C++编程法则365天一天一条(18)必须使用【初始化列表】初始化数据成员的三种情况
注意:构造函数需要初始化的数据成员,不论是否显示的出现在构造函数的成员初始化列表中,都会在该处完成初始化,并且初始化的顺序和其在类中声明时的顺序是一致的,与列表的先后顺序无关,所以要特别注意,保证两者顺序一致才能真正保证其效率和准确性。情况一的说明:数据成员是对象,并且这个对象只有含参数的构造函数,没有无参数的构造函数,这时要对这个类成员进行初始化,就必须调用这个类成员的带参数的构造函数,如果没有初始化列表,那么他将无法完成第一步,就会报错。情况一、需要初始化的数据成员是对象的情况。转载 2021-11-21 01:59:29 · 1772 阅读 · 0 评论 -
C++编程法则365天一天一条(19)构造函数的三种调用形式
👀 作者简介: 热衷于知识探索和分享的技术博主。💂 csdn主页::【✍️ 微信公众号:【🎉精彩专栏:💪 【🎓 【 🧡 【 📚 【 🌎 【✍️ 【🤩 【😉 【🥰 【🔥 【✨ 【🎉 【🤔 【✔️ 【🚀 【😊 【 …💂关于作者: 曾就职于国内知名安防上市公司,现就职于国内知名AMR机器人公司,担任高级系统软件工程师。2020年至今保持CSDN博客专家,CSDN C/C++领域优质创作者头衔。全网5万+粉丝。十载寒冰,难凉热血;原创 2020-11-29 23:24:03 · 2973 阅读 · 2 评论 -
C++编程法则365天一天一条(20)聚合类型和聚合初始化
首先,数组是聚合类型的(即使它的元素是非聚合类)。class、struct、union也可以是聚合类型,但要满足一些条件。聚合类(aggregate class)使用户可以直接访问其成员,并且具有特殊的初始化语法。当一个类满足以下条件时,我们说它是聚合的:所有成员都是public没有定义构造函数没有类内初始值没有基类,也没有虚函数聚合类可以有非public的static数据成员。聚合类可以有成员函数。聚合类可以有用户自定义析构函数、赋值运算符。class NotAggregate1{原创 2021-05-20 00:19:08 · 1174 阅读 · 0 评论 -
C++编程法则365天一天一条(21) 左值右值一文说清
左值和右值相信困扰了绝大多数的C++开发者,而且网上关于左右值的解释大多存在不严谨的地方。今天,以C++权威标准https://en.cppreference.com/w/cpp/language/value_category来学习左值和右值。左值最开始的含义是可以出现在赋值表达式左边,然而如今这一说法已经不准确。首先C++ 新标准重新做了分类,引入了glvalue、prvalue、xvalue几个新概念。在C++11中所有的值必属于左值、右值两者之一,右值又可以细分为纯右值、将亡值。原创 2021-03-21 15:05:11 · 679 阅读 · 0 评论 -
C++编程法则365天一天一条(23)关于&、&&修饰成员函数的含义
参考:https://en.cppreference.com/w/cpp/language/member_functions#member_functions_with_cv-qualifiers。目的很显然,就是为了区分传递进来的对象是左值还是右值,如果传递进来的对象是右值,那么直接剥夺(move)它的资源挪为己用,&、&&可以用于修饰成员函数,并且像const一样,可以重载。左值版本的GetText就没办法,总不能把左值的资源给剥夺了。&标识的传入成员函数的this指针指向的是一个左值,原创 2023-03-11 22:44:41 · 1838 阅读 · 0 评论 -
C++编程法则365天一天一条(24)RTTI运行时类型信息typeid和type_info
它的确切定义编译器相关的,但是标准却规定了其实现必需提供如下四种操作(在之后的章节中我会来分析type_info类文件的源码)如果表达式的类型是类类型且至少包含有一个虚函数,则typeid操作符返回表达式的动态类型,需要在运行时计算;头文件,并使用表达式作为其操作数。通常,可以将变量、对象或类型名称作为表达式。是 C++ 的一个运算符,它用于获取表达式的类型信息。否则,typeid操作符返回表达式的静态类型,在编译时就可以计算。对象引用,该对象包含有关表达式的类型的信息。在上述代码中,我们使用。原创 2023-12-09 23:47:54 · 481 阅读 · 0 评论 -
C++编程法则365天一天一条(25) 类静态成员函数的定义和调用方式,实际应用
public:public:void Some::Test() { //此处不能加static类外定义时不能加static。原创 2020-12-06 18:25:14 · 18336 阅读 · 1 评论 -
C++编程法则365天一天一条(26)谈谈类的静态成员变量
family_在这里是科的意思,例如一个动物属于什么科,这是一个固有属性,同一科的所有的对象共享该属性,没必要每一个对象都单独存储该属性。静态成员变量需要在类外进行初始化,不能在类内初始化,即使初始化列表方式也不能(因为静态成员变量不属于对象),但可以选择不初始化。对象会在程序的任何时刻创建,能在所有对象中共用的,意味着生命周期是整个程序运行期,存放在静态存储区。每创建一个类对象,类成员变量就会多出一份,各个对象间的成员变量是各自独立的变量。const静态成员变量可以在定义时初始化,也可以在类外初始化。原创 2020-12-06 18:23:43 · 16117 阅读 · 1 评论 -
C++编程法则365天一天一条(30)模板类的继承
如果父类是一个模板类,需要使用作用域限定符来指定要调用的方法属于哪个特定的实例化版本。原创 2021-01-03 22:23:06 · 2546 阅读 · 0 评论 -
C++编程法则365天一天一条(31)struct与class的区别
成员默认权限不同,class默认是private,struct默认是public默认继承权限不同,class继承默认是private继承,而struct默认是public继承class还可用于定义模板参数,作用同typename,但是关键字struct不能同于定义模板参数。原创 2020-11-29 20:50:40 · 3605 阅读 · 1 评论 -
C++编程法则365条一天一条(44)friend友元函数
friend关键字用于将函数(可以是普通函数,类成员函数,甚至是构造、析构函数)或者类声明为类的朋友,作为朋友,它可以直接访问类的私有和保护成员,公有成员自然不必说。换言之,friend打破了权限访问控制的限制,也有人说friend破坏了数据的封装。通常在类里面书写friend声明,在类外补充实现。当然,如果是普通函数,也可以直接在声明为friend的同时补全实现。p . a = i;a = i;原创 2023-03-12 00:10:46 · 149 阅读 · 0 评论 -
C++编程法则365天一天一条(45)适当运用这些编译标记
C++14中增加了[[deprecated]]标记,可以修饰类、函数、变量等,当程序中使用了被其修饰的模块时,编译器会产生告警,提示用户该标记标记的内容将来可能会被废弃,尽量不要使用。通过在函数或方法声明前加上 [[nodiscard]] 属性,我们可以告诉编译器,如果调用者忽略了该返回值,就发出一个编译警告。在大多数情况下,我们应该遵循传统的写法,在每个。是一个 C++11 中引入的属性(attribute),用于告诉编译器在。然而,在某些情况下,我们希望在某个。属性,我们可以告诉编译器,在执行完该。原创 2022-09-21 00:10:28 · 938 阅读 · 0 评论 -
C++编程法则365天一天一条(60)改革不彻底的产物:字符串视图string_view
是 C++17 引入的一个字符串视图类。它是一个轻量级、非拥有、只读的字符串查看器,可以用于以只读方式访问字符串的连续字符序列,而无需复制字符串数据。python里一切皆对象,包括字符串字面量,提供了一种类似于Python字符串对象的方式来处理字符串字面量,但改革得没有python彻底,毕竟还需要构造转换而非编译层面支持。下面是非拥有性不拥有字符串数据,它仅仅是对现有字符串的引用或视图。这意味着它不负责管理字符串的生命周期,需要确保字符串数据的生存期足够长,防止出现空悬指针的风险。只读性。原创 2024-05-19 12:01:38 · 66 阅读 · 0 评论 -
C++编程法则365条一天一条(110)using用法之别名
大家都知道,在 C 中可以通过 typedef 重定义一个类型:typedef unsigned int uint_t;被重定义的类型并不是一个新的类型,仅仅只是原有的类型取了一个新的名字。因此,下面这样将不是合法的函数重载:void func(unsigned int);void func(uint_t); // error: redefinition使用 typedef 重定义类型是很方便的,但它也有一些限制,比如,无法重定义一个模板。想象下面这个场景:typedef std::map&原创 2021-04-10 15:23:38 · 5524 阅读 · 3 评论 -
C++编程法则365天一天一条(124) final禁用继承与虚函数重写
还需要注意的点是,final需要加在最后一层被禁止重写的虚函数后,否则不生效。比如你想A类的虚函数func不被子类B重写,那么你加在子类B的虚函数func是不起作用的。C++11把它作为为了在特定上下文和位置下获取特殊意义的标示符。在任何其他位置或上下文,它都被当成普通用户标识符。我们需要注意的是,final有严格的摆放位置,只能紧跟在被修饰类的名字后面,或者是被修饰虚函数的括号后面。例如,你可以定义一个变量or函数叫final。修饰虚函数,使其无法被派生类重写。注意,只能修饰这两个东西。原创 2021-04-28 01:07:05 · 4430 阅读 · 2 评论 -
C++编程法则365天一天一条(174)熟悉文件按行读取--多种定义的getline函数使用
而回车和设置的终止符都是终止getline()函数的读取操作的。但是while判断语句判断的是getline()函数的输入流是否有效。在这之中可能会用些同志误以为while判断语句的判断对象是line(也就是line是否为空),想通过回车来跳出循环,却发现不能跳出循环。在不自定义设置的情况下,遇到’\n’,则终止输入。这个语句中,while判断语句的真实判断对象是cin的状态,也就是判断当前是否存在有效的输入流。而输入流是对象,判断的是流返回的状态。所以正常的情况下,你怎么输入都是跳不出它的循环。原创 2020-12-06 21:50:09 · 17638 阅读 · 0 评论 -
C++编程法则365天一天一条(200)using用法之声明
将定义在别处的变量、类型或者函数引入到using声明语句所在的作用域为类型起别名。我们今天主要看声明的用法。原创 2023-03-11 16:46:30 · 550 阅读 · 0 评论 -
C++编程法则365天一天一条(205)标准输入输出库介绍
面向对象的流式输入/输出库(OOP-style stream-based I/O library): 这是C++中最常用的输入/输出库,使用 头文件。它基于流(stream)的概念,提供了一组类和函数,用于进行控制台输入输出、文件读写以及字符串读写等操作。主要类包括 std::iostream、std::istream、std::ostream,以及派生类如 std::ifstream、std::ofstream 等。这些类可以通过重载操作符来进行输入和输出。原创 2023-10-06 20:37:55 · 224 阅读 · 0 评论 -
C++编程法则365天一天一条(206)关于文件流fstream
今天我们的操作都是基于std::fstream,但我们要从另外一个东西谈起:。std::basic_fstream继承于basic_iostream,basic_stream实现了基于文件流的输入输出操作,第一个模板参数类型指定了以什么为单位来操作流。而fstream是该模板类的一个特化版本(指定了处理的字符类型为char),指定了按char类型来操作流。定义于头文件的std命名空间内。原创 2021-02-27 21:12:06 · 6809 阅读 · 2 评论 -
C++编程法则365天一天一条(207)文件读写操作文件流
到目前为止,我们已经使用了 iostream 标准库,它提供了 cin 和 cout 方法分别用于从标准输入读取流和向标准输出写入流。本教程介绍如何从文件读取流和向文件写入流。这就需要用到 C++ 中另一个标准库 fstream,它定义了三个新的数据类型:数据类型描述ofstream该数据类型表示输出文件流,用于创建文件并向文件写入信息。ifstream该数据类型表示输入文件流,用于从文件读取信息。fstream该数据类型通常表示文件流,且同时具有 ofstream转载 2020-12-06 21:55:33 · 5531 阅读 · 1 评论 -
C++编程法则365天一天一条(208)std::stringstream流式字符串
是一个模板类,用于实现基于字符串的流的输入和输出操作。它内部实际上维护了一个对象,用于对字符串进行低层输入和输出的操作。同时,它也继承了std::basic_iostream` 的接口,提供了更高级别的输入和输出操作。是一个模板类,用于在内存中实现字符串缓存区。它提供了一些与相同的接口,包括sputc()sputn()sgetc()sgetn()等函数,可以用来对字符串进行读取和写入。在中,这些函数被封装在更高级别的operatorgetline()ignore()原创 2021-07-02 09:49:11 · 1088 阅读 · 2 评论 -
C++编程法则365天一天一条(323)main函数执行之前和之后的动作
在C和C++程序中,main函数之前和之后执行的函数是由编译器、链接器和运行时环境共同决定的。原创 2024-06-02 22:47:52 · 504 阅读 · 0 评论 -
C++编程法则365天一天一条(210) 纯虚析构函数见过吗
effective c++这本书告诫我们,使用多态时,务必要把父类的析构函数声明为虚函数。换句话就是,只要父类中有一个虚函数,那么父类的析构函数就必须声明为虚函数。原因很简单,当析构指向子类对象的父类指针或者引用时,才能正确地调用到子类的析构函数,而非父类的析构函数。这个很好理解,不要把析构函数看得很特殊,它也是普通函数。那么什么是纯虚析构函数呢?大家可能有个误区,纯虚函数不能有实现,因为我们没看过纯虚函数有过函数体。事实上,纯虚函数可以有默认实现。普通的成员函数,如果声明为纯虚函数,那么该类就无法原创 2020-12-27 11:53:31 · 1120 阅读 · 0 评论