首页
学习
活动
专区
工具
TVP
发布
精选内容/技术社群/优惠产品,尽在小程序
立即前往

学过 C++ 的你,不得不知的这 10 条细节!

析构函数 析构函数 可以发现在进入 operator== 函数时,发生了「复制构造函」,当离开该函数作用域后发生了「析构函数」。...当 const 和 non-const 成员函数有着实质等价的实现时,令 non-const 版本调用 const 版本可避免代码重复。...默认构造函数和析构函数主要是给编译器一个地方用来放置隐藏幕后的代码,像是调用基类和非静态成员变量的构造函数和析构函数。...消除这个问题的做法很简单:为了避免泄漏内存和其他资源,需要把基类的析构函数声明为 virtual 析构函数。...因此,无端地将所有类的析构函数声明为 virtual ,是错误的,原因是会增加不必要的体积。

75520

【C++进阶篇】像传承家族宝藏一样理解C++继承

为了访问基类的 _num,我们使用了 Person::_num 来显式地指定访问基类中的成员。这样可以避免由于成员同名而导致的混淆。 实际开发中不建议写同名的变量名或函数名。...5.2.3 析构函数调用顺序 与构造函数的调用顺序相反,析构函数的调用顺序是先调用派生类的析构函数,然后再调用基类的析构函数。这确保了派生类的资源先被释放,然后基类的资源才能安全地释放。...5.2.4 虚析构函数 在继承体系中,若希望基类指针指向派生类对象,并通过该指针安全地释放对象,基类的析构函数应当定义为虚函数。...解释: 在这个例子中,基类的析构函数被声明为虚函数,因此当delete basePtr被调用时,程序会首先调用派生类的析构函数Derived::~Derived(),然后再调用基类的析构函数Base...析构函数必须为虚函数:当基类指针指向派生类对象时,析构函数必须声明为虚函数,以确保派生类的资源能够被正确释放,避免内存泄漏。

10810
  • 您找到你想要的搜索结果了吗?
    是的
    没有找到

    【笔记】《Effective C++》条款1-25

    STL的所有容器都没有虚函数 C++11后引入了final关键字可以用来中断类后续的继承行为 当程序在析构的时候, 会从最深处开始析构, 逐步调用析构函数, 因此基类的虚析构需要一个定义, 可以是空定义...8 别让异常逃离析构函数 由于在C++中两个异常同时存在会导致未定义行为, 因此我们不应该让析构函数上报异常, 这是因为析构函数是会被自动调用的, 当一个对象析构而抛出异常时, 同个作用域的其它对象的析构也会被自动执行...close函数来执行和析构同样的行为, 这样用户就能自己处理可能发生的析构的异常, 同时依然要给真正的析构用try-catch包裹起到双保险的作用 9 绝不在构造和析构过程中调用virtual函数 派生类构造期间...析构函数尽管调用顺序相反但是思路一致 所以不要在析构/构造过程中调用虚函数 补偿方法是将需要让派生类执行的函数以非虚函数的形式写好, 然后将其所需的变量通过构造函数在构造初值列中进行传递...., 也就是由拷贝构造函数生成 因此如果只是简单地传入对象会浪费很多的构造/析构操作, 最好的做法是传const引用 传const是为了让调用的人放心传入, 同时传入引用还能避免对象切割问题(派生类传入声明为基类的参数时派生类会退化为基类

    1.1K30

    《深入理解 C++中的 RAII:资源管理的利器》

    具体来说,就是在对象的构造函数中获取资源,在对象的析构函数中释放资源。这样,无论对象是通过正常路径还是异常路径退出其作用域,资源都能被正确地释放,从而避免了资源泄漏和其他资源管理相关的问题。...而使用 RAII 技术,我们可以将文件的打开和关闭操作封装在一个类中,在构造函数中打开文件,在析构函数中关闭文件。这样,无论在对象的生命周期内发生什么情况,文件都能被正确地关闭。...使用类封装资源 实现 RAII 的最常见方法是使用类来封装资源。在类的构造函数中获取资源,在析构函数中释放资源。这样,当对象被创建时,资源被自动获取;当对象被销毁时,资源被自动释放。...例如,如果我们需要管理一个数据库连接,可以创建一个 DatabaseConnection 类,在构造函数中建立数据库连接,在析构函数中关闭数据库连接。...资源的正确获取和释放 在实现 RAII 时,必须确保资源在构造函数中被正确地获取,并且在析构函数中被正确地释放。如果资源的获取或释放过程中可能会抛出异常,需要进行适当的异常处理,以确保资源不会泄漏。

    21710

    七、构造函数与析构函数

    七、构造函数与析构函数 构造函数 在C++中,构造函数是一种特殊的成员函数,它用于初始化类的对象。当创建类的对象时,构造函数会被自动调用。...构造函数可以抛出异常,但通常建议避免在构造函数中抛出异常,因为这可能导致资源泄漏或其他问题。 构造函数可以是虚函数(在基类中),但通常不建议这样做,因为虚函数主要用于在派生类中重写基类中的函数。...因此,析构函数中应尽量避免抛出异常。 总结 构造函数和析构函数是C++中用于管理对象生命周期的特殊成员函数。...可以避免一些不必要的赋值操作,从而减少代码量,提高效率。 委托构造 委托构造是C++11引入的新特性,允许一个构造函数调用另一个同类的构造函数,以避免代码重复。...委托构造的使用场景包括: 当类有多个构造函数,并且它们之间有共同的初始化逻辑时,可以使用委托构造来避免代码重复。 当你想要在一个构造函数中扩展另一个构造函数的行为时。

    14010

    【C++修炼之路】15.C++继承

    对于我们一直遵循的代码尽量复用的原则,为的就是避免代码造成冗余,尤其是函数的使用;那对于上述的类来说,每一个类都重复了一次人类最基本的属性,这样也会造成代码的冗余,如果我们把这几个类的公共属性像在排序中的交换函数一样给提炼出来从而单独变成一个函数一样...,那么这个公共属性是不是就避免了代码的重复使用了呢?...四.派生类的默认成员函数 在最初的类和对象章节,讲过默认生成的四个成员函数:构造函数、拷贝构造函数、析构函数、赋值运算符重载。...子类析构函数和父类析构函数构成隐藏关系。...发现顺序: 构造: 基类先构造,派生类后构造。 析构: 派生类先析构,基类后析构。 4.5 总结 派生类的构造函数必须调用基类的构造函数初始化基类的那一部分成员。

    55700

    C++的new和delete详解

    言归正传,我们还能从上面的代码中看出new和delete操作其实是分别进行了2步操作:1.内存的分配,2.构造函数的调用;3.析构函数的调用,4.内存的销毁。...所以当对象是从堆内存分配时,构造函数执前内存就已经完成分配,同样当析构函数执行完成后内存才会被销毁。...这里面一个有意思的问题就是当我们分配或者销毁的是数组对象时,系统又是如何知道应该调用多少次构造函数以及调用多少次析构函数的呢?答案就是在内存分配里面。...当对数组对象调用构造和析构函数时就可以根据这个数量值来进行循环处理了。...还有一种情况是不希望进行频繁的堆内存分配和释放而只是对同一块内存进行重复的对象构建和销毁。

    1.1K50

    (大boss)C++惯用法之copy-swap

    C++惯用法之copy-swap 为什么我们需要复制和交换习惯? 任何管理资源的类(包装程序,如智能指针)都需要实现big three。尽管拷贝构造函数和析构函数的目标和实现很简单。...但是复制分配运算符无疑是最细微和最困难的。 应该怎么做?需要避免什么陷阱? copy-swap是解决方案,可以很好地协助赋值运算符实现两件事:避免代码重复,并提供强大的异常保证。 它是如何工作的?...为了使用copy-swap,我们需要三件事: 一个有效的拷贝构造函数 一个有效的析构函数(两者都是任何包装程序的基础,因此无论如何都应完整)以及交换功能。...交换函数是一种不抛异常函数,它交换一个类的两个对象或者成员。我们可能很想使用std :: swap而不是提供我们自己的方法,但这是不可能的。...当copy构造为上述的方法4时,对于C++ 11,编译器会依据参数是左值还是右值在拷贝构造函数和移动构造函数间进行选择: smart_ptr &operator=(smart_ptr rhs) noexcept

    1.6K20

    类和对象 _ 剖析构造、析构与拷贝

    对象在销毁时会自动调用析构函数,完成对象中资源的清理工作。 特性 析构函数名是在类名前面加上“ ~ ” 无参数和返回值 ~Stack() { } 一个类只能有一个析构函数。...main() { TestStack(); return 0; } 析构函数的析构过程解析 当正确使用析构函数后就不用担心程序中有内存泄漏的情况了,因为在每次该对象生命周期结束后都会自动调用析构函数...如何定义和使用拷贝构造函数 定义 浅拷贝 浅拷贝只是简单地复制对象的成员变量值,包括指针成员的地址,而不是复制指针所指向的内容。...而在拷贝构造函数中呢,也相当于类(形参) = 类(实参),这样不也相当于拷贝构造吗?所以也会进行调用拷贝构造函数,如此下来,就陷入了拷贝构造函数的无限循环调用。...所以我们在使用拷贝构造函数的时候要注意避免陷入无限循环: 形参使用引用方式 不在拷贝构造内进行拷贝构造 默认拷贝构造函数 当你没有显式地为类定义一个拷贝构造函数时,C++编译器会自动生成一个默认的拷贝构造函数

    13310

    《逆袭进大厂》第二弹之C++进阶篇59问59答(超硬核干货)

    3) 而在C++中,初始化时在执行相关代码时才会进行初始化,主要是由于C++引入对象后,要进行初始化必须执行相应构造函数和析构函数,在构造函数或析构函数中经常会需要进行某些程序中需要进行的特定操作,并非简单地分配内存...具体地说,如果派生类中申请了内存空间,并在其析构函数中对这些内存空间进行释放。...中的构造和析构函数,从实验结果来看,语句1并没有体现,执行流程是先构造基类,所以先调用基类的构造函数,构造完成再执行A自己的构造函数,析构时也是调用基类的析构函数,也就是说构造和析构中调用虚函数并不能达到目的...,应该避免 《构造函数或者析构函数中调用虚函数会怎么样?》...如果一块内存被shared_ptr和weak_ptr同时引用,当所有shared_ptr析构了之后,不管还有没有weak_ptr引用该内存,内存也会被释放。

    2.4K40

    《C++Primer》第十八章 用于大型程序的工具

    1.3 析构函数与异常 析构函数总是会被执行的,但是函数中负责释放资源的代码 却可能被跳过。 如果一个块分配了资源,并且在负责释放这些资源的代码前面发生了异常,则释放资源的代码不会被执行。...函数try语句使得一组catch语句既能处理构造函数体(或析构函数体),也能处理构造函数的初始化该过程(或析构函数的析构过程): template T> BlobT>::Blob(...函数和模板等,不可避免会出现某些名字相互冲突的情况。...// D2一旦定义了它自己的构造函数, 则必须出现 }; 1.3 析构函数与多重继承 派生类的析构函数只负责清除派生类本身分配的资源,派生类的成员以及基类都是自动销毁的。...析构函数的调用顺序正好与构造函数相反,在上面的例子中析构函数的调用函数是: ~Panda ~Endangered ~Bear ~ZooAnimal 1.4 多重继承的派生类的拷贝与移动操作 与只有一个基类的继承一样

    1.4K20

    【C++】基础:Effective C++高效编程建议

    了解 C++ 为你偷偷地加上和调用了什么函数 编译器可以隐式生成一个 class(类)的 default constructor(缺省构造函数),copy constructor(拷贝构造函数),copy...绝不要在 construction(构造)或 destruction(析构)期间调用 virtual functions(虚函数) 在 construction(构造)或 destruction(析构)...期间不要调用 virtual functions(虚拟函数),因为这样的调用不会转到比当前执行的 constructor(构造函数)或 destructor(析构函数)所属的 class(类)更深层的...RAII 原则规定了这样一个类的基本结构,通过构造函数获取资源并通过析构函数释放它: class Lock { public: explicit Lock(Mutex *pm) : mutexPtr...争取异常安全(exception-safe)的代码 即使当异常被抛出时,异常安全的函数不会泄露资源,也不允许数据结构被恶化。这样的函数提供基本的,强力的,或者不抛出保证。

    22210

    【C++】掌握C++类的六个默认成员函数:实现高效内存管理与对象操作

    ,并且在对象整个生命周期内只调用一次 构造函数目的:默认构造函数是为了解决创建对象,忘记对其对象进行初始化操作,同时解决麻烦地调用Init函数。...而是对象在销毁时自动调用析构函数,完成对象中资源的清理工作 这里资源一般指动态开辟的资源,如果没有析构函数进行处理,而是单纯地开辟和销毁对象。...对象生命周期结束时,C++编译系统自动调用析构函数 3.2 验证是否会自动调用析构函数 析构函数对于内置与自定义类型的处理方式(调用析构函数中this指针存储对象的地址) 对于内置与自定义类型处理: 内置类型不处理...Time类的_t对象销毁,但是这里不是直接调用Time类的析构函数。...(3); s1.Push(4); Stack s2(s1); return 0; } 报错原因:从图中来看,两个对象同时指向同一块空间,当对同一块空间重复析构就会报错。

    12100

    C++ 类使用规范建议

    可以考虑在类的private中添加空的(dummy)拷贝构造函数和赋值操作,只有声明,没有定义。由于这些空程序声明为private,当其他代码试图使用它们的时候,编译器将报错。...5.析构函数 析构函数(destructor) 与构造函数作用相反,当对象结束其生命周期时(例如对象所在的函数已调用完毕),程序自动执行析构函数,释放对象占用的内存资源。...(2)一般情况下,应该避免在构造函数和析构函数中调用虚函数,如果一定要这样做,程序猿必须清楚,这时对虚函数的调用其实是实调用。可参考博客:C++不要在构造函数和析构函数中调用虚函数。...(3)基类如果有虚函数函数,那么令析构函数为virtual。原因是保证通过基类指针能够动态的调用子类析构函数,避免内存泄露。...定义:当一个类满足以下要求时,称之为纯接口: (1)只有纯虚函数("=0")和静态函数(下文提到的析构函数除外); (2)没有非静态数据成员; (3) 没有定义任何构造函数。

    1.8K20

    【C++高阶】C++继承学习手册:全面解析继承的各个方面

    派生类会继承基类的成员和成员函数,同时还可以添加自己的成员和成员函数。这种能力使得我们能够构建出复杂的类层次结构,实现代码的模块化和复用 在本文的学习中我们不仅仅要了解继承的基本概念。...在实际编程中,我们还需要掌握如何正确使用继承、如何避免常见的继承陷阱、以及如何利用继承来优化我们的代码结构。...因为这样才能保证派生类对象先清理派生类成员再清理基类成员的顺序 派生类对象初始化先调用基类构造再调派生类构造 派生类对象析构清理先调用派生类析构再调基类的析构 因为后续一些场景析构函数需要构成重写,重写的条件之一是函数名相同...,但是析构必须先子后父,来避免析构完父类之后,子类出错 继承默认函数的实现代码示例 class A { public: A() {} A(int a) :_a(a) { cout <...总结 回顾学习过程,我们学会了如何定义基类与派生类,掌握了访问控制规则,理解了构造函数与析构函数在继承中的作用,还探讨了多重继承及其带来的挑战。

    43110

    C++反汇编第二讲,不同作用域下的构造和析构的识别

    E2函数内部则会调用析构函数,有人会说,为什么不直接将析构注册为函数回调,这样直接调用atexit不就在释放的时候,从后往前依次调用析构的了吗....二丶对象作为函数参数的识别 高级代码:   PS: 为了节省篇幅,类的定义不在重复截图,重复定义了. void foo(MyTest test) { printf("333\r\n"); }...内部会有个Jmp来调用析构 总结:  当函数参数为对象的时候.   1.会先在函数外部进行构造一次   2.调用函数   3.函数内部调用一次析构   4.函数结束之后的外面调用一次析构函数....其内部调用构造和析构 总结:  1.this指针会当做参数传递给函数, Mytest t = Getobj() t会当做参数传递   2.其函数内部开始的时候会调用构造函数,结束之前调用析构   3....加上类域则可以调用构造了,那么析构我们是显示调用,所以看看汇编代码,会传入0,不会释放内存的. ?

    1.1K100

    智能指针

    解决方法 析构函数中不要抛出异常: 析构函数应该尽量捕获所有异常,确保不抛出。...其核心思想是将资源的管理与对象的生命周期绑定,通过对象的构造函数获取资源,并在析构函数中释放资源。RAII的优点包括: 避免资源泄漏:当对象生命周期结束时,资源会被自动释放。...RAII 思想 RAII 是智能指针的核心设计思想,资源的获取和释放分别绑定到智能指针对象的构造函数和析构函数中: 构造函数:获取资源(如内存、文件句柄等)。 析构函数:释放资源。...不增加引用计数,避免循环引用问题。 析构器的自动调用 智能指针的一个核心特点是:在智能指针对象的生命周期结束时,其析构函数会被自动调用,确保资源的正确释放。...例如,将动态分配的资源封装到一个类中,在类的析构函数中释放资源。

    30410

    智能指针在面试中得重要地位!

    ,基类中必须具备一个虚析构函数 }; //改进的返回值型别 template析构器可能是函数对象,函数对象可以包含任意数量的数据,这意味着它们的尺寸可能是任意大小 //std::shared_ptr如何能够在不使用更多内存的前提下,指涉到任意尺寸的析构器?...,第二次析构就会引发未定义行为 //因此可以得到两个结论: /** 1,尽可能避免将裸指针传递给一个 std::shared_ptr的构造函数,替代手法是使用 std::make_shared,但是使用了自定义析构器...,型别形参总是其派生类地类名,它定义了一个成员函数,会创建一个 //std::shared_ptr指涉到当前对象,但同时不会重复创建控制块,安全实现如下 void WidgetOK::process()...(params)...)); } //好处一:避免了代码冗余 写两遍 //好处一: 避免了代码冗余 写两遍 class Widget{ }; //使用make系列函数 auto upw1(

    1K20

    Google C++编程风格指南(四)之类的相关规范

    可以考虑在类的private中添加空的(dummy)拷贝构造函数和赋值操作,只有声明,没有定义。由于这些空程序声明为private,当其他代码试图使用它们的时候,编译器将报错。...(2)一般情况下,应该避免在构造函数和析构函数中调用虚函数,如果一定要这样做,程序猿必须清楚,这是对虚函数的调用其实是实调用。可参考博客:C++不要在构造函数和析构函数中调用虚函数。...(3)基类如果有虚函数函数,那么令析构函数为virtual。原因是保证通过基类指针能够动态的调用子类析构函数,避免内存泄露。...定义:当一个类满足以下要求时,称之为纯接口: 1) 只有纯虚函数(”=0”)和静态函数(下文提到的析构函数除外); 2) 没有非静态数据成员; 3) 没有定义任何构造函数。...参考文献 [1] C++构造函数和析构函数中抛出异常的注意事项 [2]C++不要在构造函数和析构函数中调用虚函数 [3]百度文库.Google C++编码规范中文版 [4]李健.编写高质量代码

    87921
    领券