CPP
文章平均质量分 60
Tim_10
这个作者很懒,什么都没留下…
展开
专栏收录文章
- 默认排序
- 最新发布
- 最早发布
- 最多阅读
- 最少阅读
-
【C++】026、C++内存分布:全局变量、局部变量、static变量、const常量
1、全局静态看程序生命周期(全局/静态区),局部临时变量看栈空间(Stack),动态申请看堆空间(Heap),字面常量只读区(常量区),函数指令代码区(.text)未初始化的全局变量和静态变量的默认值为0;因为.bss段数据在程序加载时由操作系统强制清零(memset),只有栈上的局部未初始化变量才是随机值。2、特殊情况:全局const在常量区,局部cosnt在栈区。原创 2026-08-19 20:10:07 · 237 阅读 · 0 评论 -
【C++】023、移动语义&深拷贝
深拷贝会复制整个底层数据,让源对象和目标对象都拥有自己独立的堆内存空间移动语义是转换底层资源的所有权,将源对象的指针指向目标对象,而不赋值底层数据,时间复杂都为1移动语义将源对象的资源指针移动到目标对象,并将源对象指针设置为nullptr,这样源对象的析构操作就不会释放已经释放的资源了。移动构造函数,与移动赋值操作符函数实现 外部调用代码三、移动语义操作中置空源对象的原因?1、防止双重释放: 如果源对象的析构函数被调用时,m_data还指向原来的地址,他就会delete[]这原创 2026-08-05 19:59:31 · 174 阅读 · 0 评论 -
【C++】022、深拷贝&浅拷贝
移动是把源对象的指针直接置空(nullptr),并把指针值偷给目标对象,移动后的源对象处于有效但未指定的状态,他的析构函数不会再释放资源。如果一个类需要自定义析构函数释放资源,那么一定需要自定义拷贝构造函数和拷贝赋值运算符,以及C11后的移动构造和移动赋值。浅拷贝:仅仅逐字节复制对象本身的内存布局,两个对象中的指针成员指向同一块动态内存。反之,如果不需要析构函数,就不要自定义拷贝操作,直接让编译器生成默认的浅拷贝。C++中的移动语义既不是深拷贝,也不是浅拷贝,只是一种资源窃取。深拷贝会复制一份数据(昂贵)原创 2026-08-03 19:49:30 · 234 阅读 · 0 评论 -
【C++】021、RAII
RAII(Resource Acquisition Is Initialization)资源获取即初始化,是C++中唯一且核心的资源管理范式。RAII的设计思路是将资源的生命周期与栈上的对象的生命周期作用域进行强绑定,利用C++编译器保证确定性析构,让资源管理自动化就是让栈对象配合资源释放,无论是正常返回,还是中途抛出异常,栈对象一定会销毁,对应资源也一定会释放。原创 2026-07-30 20:29:41 · 234 阅读 · 0 评论 -
【C++】017、new/delete与malloc/free的区别
new 默认分配失败时会抛出异常 std::bad_alloc异常,使用try-catch可捕获异常,不用每次判空,也就是说使用new创建对象实例,成功了就可以直接使用,如果失败就会报错。new 先调用operate new(运算符重载)函数,来分配原始内存(底层也是调用的malloc库函数),接着调用对象的构造函数来初始化申请到的内存。new出来的内存,不能使用free进行释放,malloc也一样,因为两则new、malloc在堆管理数据结构的头部信息不同,混用会导致内存崩溃。原创 2026-07-15 20:34:29 · 195 阅读 · 0 评论 -
【C++】016、栈和堆的区别
现代C++建议尽量不用new/delete,改为使用智能指针unique_ptr 与 make_unique来申请内存。new、malloc操作后一直存在,直到delete,free被调用或进程结束,不确定强。字符串string存储位置,如果是端字符串会进行优化存储在栈上,长字符串使用堆保存。栈分配仅需一条cpu指令,堆分配涉及操作系统调用,和空闲链表遍历。变量在声明时创建,离开作用域{}时,立刻析构销毁,确定性强。每个线程拥有独立的栈空间,局部变量是线程私有的。大数据,多态对象,容器内部用堆。原创 2026-07-08 19:50:27 · 255 阅读 · 0 评论 -
【C++】015、函数参数:值传递,指针传递,引用传递的区别
指针可指向另外的对象地址,而引用不允许。实参的别名(底层也是地址)无(引用必须事先绑定对象)能(通过解引用*ptr)实参的副本(全新拷贝)实参地址(拷贝地址值)能(直接操作原对象)小(拷贝8字节地址)空值(null)风险。有(空指针需判断空)原创 2026-07-07 19:28:36 · 180 阅读 · 0 评论 -
【C++】014、左值与右值的区别
左值是有户口本的居民;右值是有暂住证的旅客;move是让居民办理临时注销,把资源合法转移给新用户。原创 2026-07-07 19:15:06 · 180 阅读 · 0 评论 -
【C++】013、空类占多少字节?
在C++中,任何完整的对象在内存中都必须具有唯一的地址// 输出:1// 输出两个不同的地址(说明确实占了1字节,地址不同)原创 2026-07-06 19:06:01 · 357 阅读 · 0 评论 -
【C++】012、typedef和using的区别
typedef和using的核心功能都是为类型创建别名(type alias),注意是给类型创建别名,让复杂类型变得简洁易读。suing是C++11引入的现在语法,优于typedef(C++98)using支持模板别名,typedef做不到。“声明式”将新名字放在类型后面,容易搞混。“赋值式”,新名字在左边,类型在右边。遵循C++作用域规则。遵循C++作用域规则。原创 2026-07-06 19:04:55 · 259 阅读 · 0 评论 -
【C++】011、mutable关键字
mutable的设计目的,是为了允许类成员变量在const成员成函数中被修改。但是这个函数希望第一次读取时计算数据并进行缓存结果,后续直接返回缓存值。将互斥锁Mutex声明为mutable,让const函数能安全地加锁。则mutable修饰的成员变量,可满足上面的要求。但mutable关键字破坏了第一个规则。不允许调用其他非const成员函数。不允许修改任何非静态成成员变量。使用const函数返回对象数据。原创 2026-07-06 19:03:38 · 255 阅读 · 0 评论 -
【C++】006、#define与const的区别
const:本质上是变量,全局const存储在.rodata段(只读数据段),局部const存储在栈(stack)上。为规避宏定义的副作用,现代C++代码实践中不建议继续使用#define,改用替代方案。#define宏定义是在预处理阶段,进行文本替换操作,属于预处理器管辖。#define使用场景,只在头文件防卫,条件编译和日志/断言中使用。他们在类型安全,作用域,内存分配和调试体验上都有着本质差异。无法调试(宏在预处理阶段已被替换,找不到相关信息)分配内容(本质是变量,存放在数据段或栈中)原创 2026-06-30 20:25:02 · 251 阅读 · 0 评论 -
【C++】002、const关键字使用
底层const (const int *),规定指向的值不能改变,赋值给int*后,约束破坏了,他可以修改对象的值。在成员函数声明末尾加const,表示该函数不会修改任何非静止成员(变量mutable成员除外)顶层const (int* const), 指向的指针不能改变,但是对象值可以改变,不受影响。const关键字在C++中不只是表示常量,他的核心是只读契约。特点:值不能改,但指针可以改(是顶层const)特点:指向不能改,但值可以改(是顶层const)用于替代#define。返回引用防止返回值修改。原创 2026-06-22 20:15:21 · 205 阅读 · 0 评论 -
[Effective C++]条款30:透彻了解inlining的里里外外
【代码】[Effective C++]条款30:透彻了解inlining的里里外外。原创 2025-04-11 17:25:25 · 757 阅读 · 0 评论 -
[Effective C++]条款29:为“异常安全”而努力是值得的
异常安全是C++编程中非常重要的概念,它确保程序在抛出异常时仍能保持数据和状态的一致性。场景:需要执行多个操作,要么全部成功,要么全部不执行。解决方案:使用copy-and-swap惯用法。3.1、使用std::exchange。原创 2025-04-09 19:12:29 · 573 阅读 · 0 评论 -
[Effective C++]条款28:避免返回handles指向对象内部成分
在C++中,返回指向对象内部成分的引用(handles)可能会导致封装性降低和对象空悬问题。为了避免這些问题,可以通过返回const引用来限制对内部数据的修改,从而确保只读访问。原创 2025-04-08 20:13:26 · 386 阅读 · 0 评论 -
[Effective C++]条款27:尽量少做转型动作
C++中,转型(cast)技术是将一种数据类型转换为另一种数据类型的过程。C++主要提供了两种主要的转型方式:旧式的C转型方式和四种新式的C++转型方式。原创 2025-04-07 19:39:52 · 1053 阅读 · 0 评论 -
[Effective C++]条款26:尽可能延后变量定义的出现时间
在C++中,尽可能延后变量定义的出现时间,主要原因是为了提供代码的可读性,减少不必要的开销以及避免潜在的错误。原创 2025-04-01 19:23:18 · 421 阅读 · 0 评论 -
[Effective C++]条款25:考虑写出一个不抛异常的swap函数
【代码】[Effective C++]条款25:考虑写出一个不抛异常的swap函数。原创 2025-03-28 18:45:45 · 610 阅读 · 0 评论 -
[Effective C++]条款24:若所有参数皆需类型转换,请为此采用non-menber函数
【代码】[Effective C++]条款24:若所有参数皆需类型转换,请为此采用non-menber函数。原创 2025-03-27 20:10:24 · 406 阅读 · 0 评论 -
[Effective C++]条款23:宁以non-member、non-friend替换member函数
这个原则的核心思想是,如果一个函数不需要直接访问类的私有或受保护成员,那么它应该被设计为非成员函数(non-member function),而不是成员函数(member function)在C++中,宁以非成员函数、非友元函数替换成员函数,的设计原则是为了增强封装性、减少类之间的耦合,并提高代码的灵活性和可维护性。有一个坐标点类Point,现在需要实现一个函数来计算两个点的距离。原创 2025-03-26 19:29:18 · 424 阅读 · 0 评论 -
[Effective C++]条款22:将成员变量声明为private
在C++中,将成员变量声明为private而不是public,主要是为了遵循面向对象编程(OOP)的封装原则。他有助于隐藏对象的内部实现细节,提供更好地控制,安全性和可维护性。原创 2025-03-24 20:15:00 · 563 阅读 · 0 评论 -
[Effective C++]条款21:必须返回对象时,别妄想返回其reference
【代码】[Effective C++]条款21:必须返回对象时,别妄想返回其reference。原创 2025-03-23 18:00:00 · 439 阅读 · 0 评论 -
[Effective C++]条款20:宁以 pass-by-reference-to-const替换 pass-by-value
在C++中,函数参数与返回值的数据传递的方式,对程序的性能和正确性有着重要影响。C++默认使用pass-by-value(传值)的方式传递参数。但这种方式在某些情况下会导致性能问题和对象切割问题。C++推荐使用pass-by-reference-to-const(传常量引用)的方式来传递参数。原创 2025-03-22 18:30:00 · 528 阅读 · 0 评论 -
[Effective C++]条款19:设计class犹如设计type
在C++中,设计一个类(class)就像设计一个新的类型(type),需要仔细考虑很多设计规范,以下是在设计类时需要考虑的问题以及对应解决方案。原创 2025-03-21 18:30:00 · 522 阅读 · 0 评论 -
[Effective C++]条款18:让接口容易被正确使用,不易被误用
C++中的接口实现有 function接口、class接口和template接口等,每一种接口都是用户与代码互动的方式。原创 2025-03-20 18:30:00 · 318 阅读 · 0 评论 -
[Effective C++]条款17:以独立语句将newed对象置入智能指针
C++标准中没有规定函数参数的求值顺序,也就是说,编译器可能会以任意顺序对参数进行求值.原创 2025-03-19 18:00:00 · 434 阅读 · 0 评论 -
[Effective C++]条款15:在资源管理类中提供对原始资源的访问
在C++中,使用RAII方式管理动态内存资源时,通常会将资源封装在一个类中。原创 2025-03-16 19:00:00 · 683 阅读 · 0 评论 -
[Effective C++]条款14:在资源管理类中小心coping行为
在C++中,RAII(Resources Acquisition Is Initialization - 资源获取即初始化)是一种重要的资源管理技术,它通过对象的生命周期来管理资源的获取和释放。当一个对象持有一个资源(如互斥锁)时,通常不希望该资源对象被拷贝或赋值,因为这可能导致资源的重复释放或竞争条件。原创 2025-03-15 19:00:00 · 327 阅读 · 0 评论 -
[Effective C++]条款13:以对象管理资源
资源使用原则: 不论哪一种资源,重要的是当你不再使用它时,必须将它返给系统。原创 2025-03-14 18:00:00 · 624 阅读 · 0 评论 -
[Effective C++]条款12:复制对象时勿忘每一个成分
在C++中,拷贝构造函数和拷贝赋值操作符是用于管理对象拷贝行为的两个重要成员函数,如果不进行自定义实现,编译器默认会默认实现这两个函数。原创 2025-03-13 16:22:17 · 1132 阅读 · 0 评论 -
C++ 浅拷贝&深拷贝
在C++中,深拷贝和浅拷贝都是对象的拷贝方式,两者的主要区别是如何处理动态分类的资源.对于程序中的资源管理错误如内存泄漏、双重释放非常重要.原创 2025-03-12 21:52:51 · 444 阅读 · 0 评论 -
[Effective C++]条款11:在operator= 中处理“自我赋值”
【代码】[Effective C++]条款11:在operator= 中处理“自我赋值”原创 2025-03-09 19:00:00 · 362 阅读 · 0 评论 -
[Effective C++]条款10:令operator= 返回一个reference to *this
* 4、this 与 *this **原创 2025-03-08 22:07:47 · 472 阅读 · 0 评论 -
[Effective C++]条款08:别让异常逃离析构函数
当异常抛出时,C++会进行栈展开,调用局部对象的析构函数。如果析构函数本身抛出异常,程序将面临两个异常同时存在的情况,这会触发std::terminate,导致程序终止。栈展开的目的是销毁当前作用域内的局部对象,并调用它们的析构函数,以确保资源被正确释放。因此,程序会调用 std::terminate,直接终止程序。如果析构函数抛出异常,可能导致资源未正确释放,因为异常会中断析构函数的正常执行流程。析构函数应确保资源释放,抛出异常会破坏这一原则,增加程序的不确定性。原创 2025-03-06 21:53:35 · 564 阅读 · 0 评论 -
[Effective C++]条款07:为多态基类声明virtual析构函数
当基类指针指向派生类对象时,如果基类的析构函数不是虚函数,那么通过基类指针删除对象时,只会调用基类的析构函数,而不会调用派生类的析构函数。将上面的基类析构函数设置为虚函数后,通过基类指针删除派生类对象时,会先调用派生类的析构函数,再调用基类的析构函数,确保所有资源正确释放。通过基类指针删除派生类对象时,编译器会根据对象的动态类型(即实际指向的派生类类型)调用正确的析构函数。如果基类的析构函数不是虚函数,编译器会直接调用基类的析构函数,而不会通过虚函数表查找派生类的析构函数。③、调用基类的析构函数。原创 2025-03-04 19:00:00 · 652 阅读 · 0 评论 -
[Effective C++]条款06:若不想使用编译器自动生成的函数,就该明确拒绝
C++11 之前,可以通过将函数声明为private,并不提供实现,用来阻止外部调用。private修饰的函数,外部不能调用。定义一个不可拷贝的基类,并让目标类继承它。因为基类显式说明没有拷贝函数和拷贝赋值操作符的函数调用功能,其派生子类也具有该特性。C++ 11引入了= delete,可以显式删除函数,明确告诉编译器不要生成delete修饰的函数了。原创 2025-03-03 19:49:12 · 269 阅读 · 0 评论 -
[Effective C++]条款03:尽可能使用const
3.3)、常量指针常量(Constant Pointer to Constant):指针本身和指针指向的值都不可修改。3.1)、常量指针(Pointer to Constant):指针指向的值不可修改,但指针本身可以指向其他地址。const关键字常用于定义常量,表示某个值、对象或指针在程序运行期间不可修改,也用于修饰函数,引用等.3.2)、指针常量(Constant Pointer):指针本身不可修改,但可以通过指针修改指向的值。const可以修饰函数的返回值,表示返回值是常量,不可修改。原创 2025-02-28 22:51:33 · 526 阅读 · 0 评论 -
[Effective C++]条款01:视C++为一个语言联邦
这个概念是由 C++ 之父 Bjarne Stroustrup 提出的,用来描述 C++ 的多范式特性和其设计哲学。C++ 并不是一个单一的语言,而是由多个子语言或范式组成的“联邦”。每种子语言都有自己的规则和特性,但它们共同构成了 C++ 的整体。原创 2025-02-27 19:57:17 · 1638 阅读 · 0 评论 -
[Effective C++]条款02:尽量以const, enum, inline替换#define
尽量以const, enum, inline替换#define原创 2025-02-27 20:09:01 · 573 阅读 · 0 评论
分享