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

《Effective C++》读书笔记(2):构造析构赋值运算

款5、了解C++默认编写并调用哪些函数 通常情况下,如果代码没有声明构造函数、拷贝构造函数、拷贝运算符、析构函数,编译器会在需要创建他们,但这往往只能满足编译器需求,很可能无法满足程序需求...不过这种操作只有类是多态用途才需要注意,也有很多类不是为了多态用途,例如STL容器和上文Uncopyable。...对于派生类构造函数而言,进入其中类部分已构造完而派生类部分未构造完,对象类型是类,故而此时调用虚函数,实际上使用函数。 析构函数同理。...进入析构函数后派生类部分呈未定义值,对象类型是类,调用函数。 总而言之,构造函数与析构函数函数行为有特殊变化;为了避免出错,不要在其过程中使用函数。...那么这样简单拷贝运算符就会出错,先释放了自身pb,又使用了pb: Widget& Widget::operator=(const Widget& rhs){ delete pb; pb =

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

☀️ 学会编程入门必备 C# 最基础知识介绍(五)——方法、封装、继承、多态

每一个 C# 程序至少有一个带有 Main 方法类。 要使用一个方法,您需要: 定义方法 调用方法 ---- C# 定义方法 当定义一个方法,从根本上说是声明它结构元素。... C# ,有三种向方法传递参数方式 方式 描述 值参数 这种方式复制参数实际值给函数形式参数,实参和形参使用是两个不同内存值。... C# 使用 按引用传递参数 引用参数是一个对变量内存位置引用。当按引用传递参数,与值参数不同是,它不会为这些参数创建一个新存储位置。...静态多态性函数响应是在编译发生动态多态性函数响应是在运行时发生 C# ,每个类型都是多态,因为包括用户定义类型在内所有类型都继承自 Object。...分别为: 函数重载 运算符重载 ---- 函数重载 可以同一个范围内对相同函数名有多个定义。函数定义必须彼此不同,可以是参数列表参数类型不同,也可以是参数个数不同。

88920

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

另外一个注意是初始化次序(顺序),初始化次序(顺序): 先是类对象,再初始化派生类对象(如果存在继承关系); 类里成员变量总是以声明次序被初始化,本例 m_Id 先被初始化,再是 m_Name...构造函数最好使用成员初值列,而不要在构造函数本体内使用赋值操作。初值列列出成员变量,其排列次序应该和它们 class 声明次序(顺序)相同。...---- 细节 09: operator= 处理「自我赋值」 「自我赋值」发生在对象被赋值给自己: class A { ... }; A a; ... a = a; // 赋值给自己 这看起来有点愚蠢...我旧文里《C++ 赋值运算符'='重载(浅拷贝、深拷贝)》规避这个问题试,就采用是方式 一,这个方式是不合适。...---- 细节 10:复制对象勿忘其每一个成分 以下我把复制构造函数赋值操作符函数,称为「copying 函数」。

70720

第 13 章 拷贝控制

其中,拷贝和移动构造函数定义了当用同类型另一个对象初始化本对象做什么。拷贝和移动赋值运算符定义了将一个对象赋予同类型另一个对象做什么。...编译器略过了拷贝构造函数 一个构造函数,成员初始化是函数体执行之前完成,且按照它们类中出现顺序进行初始化。...重载拷贝赋值运算符,要注意处理自赋值情况,一个较好方法是销毁左侧运算对象之前先拷贝右侧运算对象。 拷贝一个像值对象,副本和原对象是完全独立。...可以通过标准库 move函数来显式地将一个左值转换为对应右值引用类型。在对一个对象使用 move函数后,可以对这个移后源对象进行销毁或赋值操作,但不能再使用它!...v2 = getVec(cin); // 右侧对象是一个右值,使用移动赋值 使用拷贝并交换技术实现赋值运算符,如果在类同时定义了一个移动构造函数,则该赋值运算符实际上也是一个移动赋值运算符

97150

C++:31---对象引用和赋值

,意味着此参数要进行拷贝初始化 依赖实参类型,拷贝初始化: 要么使用拷贝构造函数——左值被拷贝 要么使用移动构造函数——右值被移动 因此,此处定义赋值运算符就实现了拷贝赋值运算符和移动赋值运算符两种功能...例如: 第一个赋值,右侧对象hp2是一个左值,因此使用拷贝构造函数来初始化 第二个赋值,我们调用std::move()将将一个右值绑定到hp2上。...交换HasPtr回交换两个对象指针(及int)成员。swap之后,rhs指针将指向原来左侧对象所拥有的string(及int)。...; //s1+s2是一个右值,我们此处对一个右值进行了赋值(无意义) 旧标准,我们没有办法阻止这种使用方式。...,引用限定符只能作用于(非static)成员函数,且声明和定义都需要 引用限定符可以和const一起使用,且const必须在限定符前面。

1.6K10

腾讯C++后台开发面试笔试知识点参考笔记

如果析构函数不被声明成虚函数,则编译器实施静态绑定,删除类指针,只会调用析构函数而不调用派生类析构函数,这样就会造成派生类对象析构不完全。所以,将析构函数声明为虚函数是十分必要。...只有成员函数代码才应该使用作用域操作符覆盖虚函数机制。 为什么会希望覆盖虚函数机制?最常见理由是为了派生类虚函数调用版本。...在这种情况下,已经确切知道调用哪个实例,因此,不需要通过虚函数机制。派生类虚函数调用类版本,必须显式使用作用域操作符。...一般我们并不关心是哪个实际类包含成员,通常只类和派生类共享同一名字才需要注意。 与类成员同名派生类成员将屏蔽对类成员直接访问。...(info1 == info2); } 复制控制 包括,一个拷贝构造函数,一个赋值运算符,一个析构函数,一对取址运算符 如果你这么写:class Empty{}; 和你这么写是一样: class Empty

96810

两万字总结《C++ Primer》要点

拷贝构造函数、移动构造函数定义了当用同类型另一个对象初始化本对象做什么。 拷贝赋值运算符、移动赋值运算符定义了将一个对象赋予同类型另一个对象做什么。 析构函数定义了当此类型对象销毁做什么。...移动赋值运算符: StrVec &StrVec::operator=(StrVec &&rhs) noexcept { } 合成移动操作: 若一个类定义了自己拷贝构造函数、拷贝赋值运算符或者析构函数...::: warning 当我么用一个派生类对象为一个类对象初始化或赋值,只有该派生类对象类部分会被拷贝、移动或赋值,它派生类部分会被忽略掉。...如果我们想拷贝(或移动)类部分,则必须在派生类构造函数初始值列表显式使用拷贝(或移动)构造函数。 ::: 派生类赋值运算符: 派生类赋值运算符必须显式为其类部分赋值。...派生类析构函数: 派生类函数只负责销毁由派生类自己分配资源。 15.8 容器与继承 当使用容器存放继承体系对象,必须采用间接存储方式。因为不允许容器中保存不同类型元素。

1.5K30

两万字总结《C++ Primer》要点

拷贝构造函数、移动构造函数定义了当用同类型另一个对象初始化本对象做什么。 拷贝赋值运算符、移动赋值运算符定义了将一个对象赋予同类型另一个对象做什么。 析构函数定义了当此类型对象销毁做什么。...移动赋值运算符: StrVec &StrVec::operator=(StrVec &&rhs) noexcept { } 合成移动操作: 若一个类定义了自己拷贝构造函数、拷贝赋值运算符或者析构函数...::: warning 当我么用一个派生类对象为一个类对象初始化或赋值,只有该派生类对象类部分会被拷贝、移动或赋值,它派生类部分会被忽略掉。...如果我们想拷贝(或移动)类部分,则必须在派生类构造函数初始值列表显式使用拷贝(或移动)构造函数。 ::: 派生类赋值运算符: 派生类赋值运算符必须显式为其类部分赋值。...派生类析构函数: 派生类函数只负责销毁由派生类自己分配资源。 15.8 容器与继承 当使用容器存放继承体系对象,必须采用间接存储方式。因为不允许容器中保存不同类型元素。

1.7K20

C++查缺补漏

,但它并不是万能 提供一个完整类声明之前,不能声明该类对象,也不能在内联成员函数使用该类对象 当使用前向引用声明时,只能使用被声明符号,而不能涉及任何细节 class Fred; /...不需要显式地调用析构函数,系统会自动隐式调用 先执行派生类析构函数函数体,再调用析构函数 访问从类继承成员 当派生类与类中有相同成员: 若未特别限定,则通过派生类对象使用是派生类同名成员...注意: 第一级继承就要将共同类设计为虚类 虚类及其派生类构造函数 建立对象所指定类称为最远派生类 虚成员是由最远派生类构造函数通过调用虚构造函数进行初始化 整个继承结构...这时,派生类函数便覆盖了函数 派生类函数还会隐藏同名函数所有其它重载形式 一般习惯于派生类函数使用virtual关键字,以增加程序可读性 虚析构函数 为什么需要虚析构函数...list[i] = a.list[i]; } //重载"="运算符,将对象rhs赋值给本对象。

2.5K10

Effective_Cpp55个建议

return *this; } 11:operator=处理自我赋值 w=w; a[i]=a[j]; *px=*py; 这几种都会发生“自我赋值”。...return *this; } 12:复制对象勿忘其每一个成分 1.如果你自己写了一个拷贝构造函数或=运算符,那么如果你在里面落掉了某个成员,编译器是不会提醒你。...3.还有如果一个子类继承了你这个类,那么这个子类调用拷贝函数,就不会自动调用父类你写拷贝函数了,需要你手动调用。...++11之后,就已经弃用auto_ptr了,可以把auto_ptr改成shared_ptr 2.为防止资源泄露,请使用RAII(资源获取时机便是初始化时机)对象,他们构造函数获得资源并在析构函数释放资源...3.切割问题:当使用传值方式,一个子类对象被传递,被当一个父类对象接收,此时只能调用父类拥有的操作,子类扩展就被切割了。 21:?必须返回对象,别妄想返回其reference。

55030

Effective c++ 小结

用 const好处是,调试,可以直接获取变量,而非定义数字,这个使用gdb跟踪代码时候很有用,比如#define NUM 123;如果在gdbprint NUM,会出现NUM找不到符号表问题...条款6:析构函数里对指针成员调用delete 这条为了防止内存泄露,具体说来要做三件事情:   每个构造函数中将该指针初始化   每个赋值运算符中将原有内存删除,重新配置一块   每个析构函数...3,基本类型non-const, non-reference对象,初始化和赋值之间没有2所说区别 条款13: 初始化列表成员列出顺序和它们声明顺序相同 编译器构造和析构顺序是相反...String& String::operator =(const String&rhs) { … return *this; } 条款16: operator=对所有数据成员赋值 原因:编译器会默认为你生成一个...(*this) = rhs两种方式解决 条款17: operator=检查给自己赋值情况 一般采用方法: C& C::operator=(const C&rhs) {

75950

《C++Primer》第十三章 拷贝控制

一个析构函数,不存在类似构造函数初始化列表东西来控制成员如何销毁,析构部分是隐式。成员销毁发生什么完全依赖于成员类型。销毁类类型成员需要执行成员自己析构函数。...阻止拷贝 虽然大多数类应该定义拷贝构造函数和拷贝赋值运算符,但是对于某些类来说这些操作没有意义。在此情况下,定义类必须采用某种机制组织拷贝或者赋值。...rhs现在指向本对象曾经使用内存 return *this; // rhs被销毁,从而delete了rhs指针 } 这个技术自动就是异常安全,且能正确处理自赋值改变左侧对象之前就拷贝右侧运算对象...我们使用一个allocator来获取原始内存,由于allocator获取原始内存是未构造,我们将在需要添加新元素使用constructor原始内存创建对象,删除元素使用destory销毁元素...如果vector使用是拷贝构造函数并且发生异常,新内存构造元素旧元素保持不变,这时候如果发生异常vector可以直接释放新分配(但还没构造成功)内存并返回。vector元素仍然存在。

1.6K40

C++:51---继承构造函数、析构函数、拷贝控制一系列规则

规则如下: 如果默认构造函数、拷贝构造函数、拷贝赋值运算符、或析构函数是被删除或者是不可访问,则派生类对应成员将是删除,原因是编译器不能使用类成员来执行派生类对象属于部分操作...当我们使用=default请求一个移动操作,如果对应操作是删除或不可访问,那么派生类函数是被删除,原因是派生类对象类部分不可移动。...virtual ~Quote() = default; //虚析构函数 }; 四、派生类拷贝控制成员 派生类执行拷贝构造函数/移动拷贝构造函数,或拷贝赋值运算符/移动赋值运算符...(std::move(d)) //别忘记移动类成员 { //函数体内移动本类成员 } }; 派生类赋值运算符 与拷贝和移动构造函数一样,派生类赋值运算符页必须显式地为其类部分赋值: 例如: class...//为类执行赋值运算符 //然后再执行本类部分 return *this; } }; 五、特别注意:构造函数和析构函数调用虚函数 根据构造函数,析构函数我们知道: 派生类构造,先构造类部分

1.2K30

CC++学习之路(一)

首先,我们先来弄懂关于构造函数定义。百度百科上,是这么定义:构造函数 ,是一种特殊方法。主要用来创建对象初始化对象, 即为对象成员变量赋初始值,总与new运算符一起使用在创建对象语句中。...(也称为拷贝构造函数)         //    复制构造函数参数为类对象本身引用,用于根据一个已存在对象复制出一个新该类对象,一般函数中会将已存在对象数据成员值复制一份到新创建对象...// 也可以使用下面的形式         Complex c3 = Complex(1.0,2.5);                 //    把c3数据成员赋值给c1        ...调用类型转换构造函数         //    系统首先调用类型转换构造函数,将5.2创建为一个本类临时对象,然后调用等号运算符重载,将该临时对象赋值给c1         c2 = 5.2;        ...只定义指针而不给指针赋值,则不涉及内存分配,不调用构造函数

78131

深入探讨 JavaScript 逻辑赋值运算符

无条件 vs 有条件 数学运算符,例如 +是无条件const x = 1 + 2,无论如何,我们总是将LHS添加到RHS,并将结果分配给x。...LHS 和 RHS 是数学领域内概念,意为等式左边和等式右边意思,我们现在场景下就是赋值操作符左侧和右侧。当变量出现在赋值操作符左边,就进行 LHS 查询;反之进行 RHS 查询 ?。...它将 LHS 添加到RHS,最后将其分配给x,得出2。 逻辑运算符,例如 &&是有条件 const x = true && 0 + 2,首先计算 LHS,它为true。...二元逻辑运算符 && || ?? JSX 我们经常使用&&和||来有条件地渲染界面。??是nullish(空值)合并运算符,它是最近刚通过提案,很快就会普及。它们都是 二元逻辑运算符。...; // 这里 myObject.c 为虚值,所以什么都不会做 如何在项目中使用逻辑赋值 Chrome 已经支持逻辑赋值。 为了向后兼容,请使用 transformer。

92920

C++10移动语义

首先,我们来看这样一个函数: (T为一个对象类型) T clone(const T& rhs) { T other = rhs; return other; } 这样函数...第一次默认拷贝构造函数调用是demo对象初始化过程; 两次拷贝构造函数实在clone函数调用过程: clone函数利用this对象初始化demo对象进行一个拷贝构造,然后返回demo...如果源对象是复制或者赋值结束以后被销毁临时对象,编译器会使用两种方法。移动构造函数和移动赋值运算符将成员变量从源对象复制/移动到新对象,然后将源对象变量设置为空值。...移动语义是通过右值引用实现C++,左值是可以获取其地址一个量,例如有名称变量。由于经常出现在赋值语句左边,因此称其为左值。所有不是左值量都是右值,例如常量、临时变量或者临时对象。...通常位于赋值运算符右边。 右值引用是一个对右值引用。特别地,这是一个当右值是临时对象使用概念。右值引用目的是提供在临时对象可选用特定方法。

47330

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

任何管理资源类(包装程序,智能指针)都需要实现big three。尽管拷贝构造函数和析构函数目标和实现很简单。 但是复制分配运算符无疑是最细微和最困难。 应该怎么做?需要避免什么陷阱?...从概念上讲,它通过使用拷贝构造函数功能来创建数据本地副本,然后使用交换功能获取复制数据,将旧数据与新数据交换来工作。然后,临时副本将销毁,并随身携带旧数据。我们剩下是新数据副本。...std :: swap实现中使用了copy-constructor和copy-assignment运算符,我们最终将尝试根据自身定义赋值运算符!...(不仅如此,对swap无条件调用将使用我们自定义swap运算符,从而跳过了std :: swap会导致不必要类构造和破坏。)...当copy构造为上述方法4,对于C++ 11,编译器会依据参数是左值还是右值拷贝构造函数和移动构造函数间进行选择: smart_ptr &operator=(smart_ptr rhs) noexcept

1.5K20

扫码

添加站长 进交流群

领取专属 10元无门槛券

手把手带您无忧上云

扫码加入开发者社群

相关资讯

热门标签

活动推荐

    运营活动

    活动名称
    广告关闭
    领券