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

C++为什么向我的类添加析构函数会使我的类不可移动?

C++为什么向我的类添加析构函数会使我的类不可移动?

在C++中,当我们定义一个类时,编译器会自动生成默认的构造函数、拷贝构造函数、拷贝赋值运算符和析构函数。如果我们手动添加了析构函数,编译器将不再自动生成移动构造函数和移动赋值运算符。

移动语义是C++11引入的一项特性,它允许对象的资源(如堆内存)在移动时进行转移,而不是进行拷贝操作,从而提高程序的性能。移动构造函数和移动赋值运算符的存在使得对象可以在不进行资源拷贝的情况下进行移动,从而提高效率。

然而,当我们手动添加了析构函数时,编译器不再自动生成移动构造函数和移动赋值运算符。这是因为析构函数的存在意味着类中可能存在需要手动释放的资源,如动态分配的内存。如果编译器自动生成了移动构造函数和移动赋值运算符,它们会简单地将资源的所有权从一个对象转移到另一个对象,而不会进行资源的释放操作。这可能导致资源泄漏或重复释放的问题。

为了避免这种潜在的问题,当我们手动添加了析构函数时,编译器不再自动生成移动构造函数和移动赋值运算符,从而防止了类的移动操作。如果我们确实需要支持移动操作,可以手动实现移动构造函数和移动赋值运算符,并在其中正确地处理资源的转移和释放操作。

总结起来,向类添加析构函数会使类不可移动,是因为编译器不再自动生成移动构造函数和移动赋值运算符,以避免潜在的资源管理问题。如果需要支持移动操作,需要手动实现移动构造函数和移动赋值运算符,并正确处理资源的转移和释放。

页面内容是否对你有帮助?
有帮助
没帮助

相关·内容

C++构造函数函数

C++中每个都有其构造与函数,它们负责对象创建和对象清理和回收,即使我们不写这两个,编译器也会默认为我们提供这些构造函数。...下面仍然是通过反汇编方式来说明C++中构造和函数是如何工作。...编译器是否真的会默认提供构造与函数 在一般讲解C++书籍中都会提及到当我们不为提供任何构造与函数时编译器会默认提供这样六种成员函数:不带参构造,拷贝构造,“=”重载函数函数,以及带const...,当父存在构造函数时,编译器会默认为子类添加构造函数,子类构造函数主要是调用父构造函数。...,但是接着执行函数函数中定义对象,接受返回值得这块内存一直等到它所在语句块结束才调用 如果不要这个返回值时又如何呢,下面的代码说明了这个问题 int main() {

1.6K10

构造函数函数

一、构造函数函数由来 数据成员不能在声明时候初始化,为了解决这个问题? 使用构造函数处理对对象初始化。...构造函数是一种特殊成员函数,与其他函数不同,不需要用户调用它,而是创建对象时候自动调用。函数是对象不再使用时候,需要清理资源时候调用。...二、构造函数 (1)初识初始化 C++支持两种初始化形式:复制初始化和直接初始化,对于直接初始化直接调用实参匹配构造函数,复制初始化总是调用复制构造函数。...三、函数 函数和构造函数作用相反,释放对象使用资源,并销毁非static成员。 (1)内存泄漏 下面代码有何隐患?...其实也是一样,上述代码就会有内存泄漏风险。如何解决呢?看下述代码。 在上述代码中,我们在函数中,添加delete函数。解决了内存泄漏问题,但是还存在其他问题。

1.8K20

使用Python构造函数函数

1、问题背景当使用Python时,可以使用构造函数函数来初始化和清理实例。构造函数在创建实例时自动调用,而函数在删除实例时自动调用。...在上面的代码示例中,Person具有一个构造函数__init__和一个函数__del__。...函数__del__在Person实例被删除时被调用,它将实例的人口计数population减1。...问题是,如果在程序中显式地删除Person实例,函数__del__是否会被自动调用,或者是否需要在“main”程序/添加一些东西,如上面的代码示例所示?...2、解决方案函数__del__会在垃圾回收器收集对象时自动调用,而不是在丢失对对象最后一个引用时,也不是在执行del object时调用。

10810

C++修行之道】和对象(二)6个默认成员函数、构造函数函数

2.4 一般情况,建议每个,都可以写一个全缺省构造(好用) 三、函数 3.1 概念 3.2 特性 3.3 C++实现括号匹配和C语言不同 一、6个默认成员函数 如果一个中什么成员都没有,...注意:函数不能重载 对象生命周期结束时,C++编译系统系统自动调用函数。...,为什么最后会调用Time函数?...但是:main函数中不能直接调用Time函数,实际要释放是Date对象,所以编译器会调用Date函数,而Date没有显式提供,则编译器会给Date生成一个默认函数。...注意:创建哪个对象则调用该类函数,销毁那个对象则调用该类函数 6.

6910

C++核心准则C.127:包含虚函数应该有虚函数或保护函数

C.127: A class with a virtual function should have a virtual or protected destructor C.127:包含虚函数应该有虚函数或保护函数‍...包含虚函数通常(大多数情况下)通过指向基指针使用。通常,最后一个使用者必须通过指向基指针调用delete操作,通常是指向基智能指针,因此函数应该是公开函数。...稍微特殊一些情况是:如果不希望支持通过指向基指针销毁对象,函数应该是保护非虚函数。参见C.35。...包含虚函数函数要么是公开函数,要么是保护非虚函数。...提示针对包含虚函数却没有虚函数销毁操作。

74720

C++】继承 ⑧ ( 继承 + 组合 模式对象 构造函数函数 调用规则 )

一、继承 + 组合 模式对象 构造函数函数调用规则 1、场景说明 如果一个 既 继承了 基 , 又 在中 维护了一个 其它类型 成员变量 , 那么 该类 构造 与 , 就需要涉及到... 本身 构造函数函数 , 父 构造函数函数 , 成员变量 构造函数函数 ; 2、调用规则 在 继承 + 组合 情况下 , 构造函数函数 调用规则如下...自身定义 构造函数 ; 函数 : 自身 -> 成员 -> 父 ; 首先 , 调用 自己 函数 ; 自身定义 函数 ; 然后 , 调用 成员 函数 ; 也就是 成员变量 类型...<< "C 函数调用" << endl; } public: int z; D d; }; 可根据下面的调用规则 , 分析出 C 对象中 , 涉及到构造/函数 , 自身构造/函数...; 然后分析 函数 调用顺序 ; C 函数 , 是 自身构造函数 ; D 函数 , 是 成员构造函数 ; A 和 B 函数 , 是 父构造函数 ; 函数调用顺序为 : 自身

16010

C++-编写String构造函数函数和赋值函数

浏览量 2 说到这题就想到了很早之前一次面试,就是由于这题被面试官说一文不值(当然说得也不错),这题是c++里面的基本题目,据说能够完整写出来的人,基础就达到了及格以上水平,在后续面试里面就没有看到这样题目...已知String原型为: class String { public: String(const char *str = NULL); // 普通构造函数 String(const String...&other); // 拷贝构造函数 ~ String(void); // 函数 String & operator =(const String &other); // 赋值函数 private...: char *m_data; // 用于保存字符串 }; 关于这道题目的解答,在网上看到一个较完整就直接发给大家看一下,如果你有些慨念不清楚,比如什么是赋值函数,它怎么样实现,以及功能是什么...m_data = new char[length+1]; // 若能加 NULL 判断则更好 strcpy(m_data, str); } } // String函数

57510

C++】从入门到精通第二弹——构造与函数

写在最前面的话 ——构造函数函数是两个特殊成员函数,都没有返回值,构造函数名和名相同,函数名只是在名前加上 ~ 构造函数主要用来在创建对象时给对象中数据成员赋值,主要目的是初始化对象..., 函数功能与构造函数正好相反,函数是用来释放对象,再删出对象前,对对象进行清理工作。...函数不能发生重载 不管是构造函数还是函数都不能使用return语句,没有返回值 在不同环境下构造函数函数调用规则如下: 自动变量作用域是某个模块,当此模块被激活时,调用构造函数,...全局变量在进入main函数之前调用构造函数,在程序终止时调用函数。 动态分配对象在使用new为对象分配内存时调用构造函数,使用delete删除对象时调用函数。...临时变量是编译器为支持计算自动产生,临时变量生存期开始和结束点会调用构造函数函数

11240

C++从入门到精通——6个默认成员函数函数

函数 前言 一、函数概念 二、函数特性 三、函数练习题 四、总结 前言 6个默认成员函数:如果一个中什么成员都没有,简称为空。 空中真的什么都没有吗?...在C++中,函数是一种特殊成员函数,用于在对象被销毁时清理其使用资源。它名称与名称相同,前面加上一个波浪线(~),没有返回类型,也不接受任何参数。...函数可以用于释放动态分配内存、关闭打开文件、释放其他资源等。它主要作用是确保对象在被销毁之前进行必要清理工作,以避免资源泄漏和不可预测行为。...注意:函数不能重载 对象生命周期结束时,C++编译系统系统自动调用函数。...,为什么最后会调用Time函数

19810

Python构造函数__init__(self)和函数__del__详解

__del__ __del__ (),被称为函数,__del__()在对象消逝时候被调用,当对象不再被使用时,__del__()方法运行。...当使用del 删除对象时,会调用他本身函数,另外当对象在某个作用域中调用完毕,在跳出其作用域同时函数也会被调用一次,这样可以用来释放内存空间。  ...__del__()也是可选,如果不提供,则Python 会在后台提供默认函数 如果要显式调用函数,可以使用del关键字:del obj class Test(object): name...__del__等所有程序执行完才会执行 #2、被del方法,无法再被调用 #3、函数会自动被调用 #4、del 方法,会调用函数 "C:\Program Files\Python35\python.exe...这里是构造方法 王大大 33 王大大 上海市 这里是函数,清理了 这里是函数,清理了

2.4K10

C++核心准则C.31:请求所有资源必须在函数释放

C.31: All resources acquired by a class must be released by the class's destructor 申请所有资源必须在函数释放...Xifstream成员通过函数隐式关闭任何它打开任何文件。...对于(通信,译者注)起始模块,函数作者并不知道函数为什么被调用,而且没有办法通过抛出异常来“拒绝处理”。...For example: 可以持有指向那些它并不拥有所有权对象指针或引用。显然,这样对象不应该被该类函数销毁。...(简单)如果类包含具有所有权(例如通过gsl::owner宣示所有权)指针或引用成员,则它们应该在函数中被引用。 译者注:个人觉得应该是在函数中释放。

56610

C++编程经验(2):为虚基做虚函数必要性

这个要提一下,如果记不住就记住:如果不做虚函数,会有内存泄漏 解释 定义一个基指针p,在delete p时,如果基函数是虚函数,这时只会看p所赋值对象,如果p赋值对象是派生对象,...就会调用派生函数;如果p赋值对象是基对象,就会调用基函数,这样就不会造成内存泄露。...如果基函数不是虚函数,在delete p时,调用函数时,只会看指针数据类型,而不会去看赋值对象,这样就会造成内存泄露。 多少学点设计模式就清楚了。...接下来是一个子类 class Inherit :public Base{ //此处省去,一切从简 }; //重点看调用 int main() { Base *p = new Inherit; //这种方式调用...,这时候有没有虚就不一样了 delete p; Base *q = new Base; delete q; return 0; }

56110

c++学习笔记4,调用派生顺序构造和函数(一个)

大家好,又见面了,是全栈君 测试源代码: //測试派生构造函数调用顺序何时调用 //Fedora20 gcc version=4.8.2 #include using namespace...a3也并没有调用基构造函数"<<endl; A *a3=&a; B b; } 输出为: 能够看到,在创建派生对象时候,首先调用是基构造函数,然后才是调用派生自己构造函数...而在时候,顺序则刚好相反,先调用派生函数,然后才是调用基构造函数。这是由于对象创建时候对象存放在堆栈中原因。(new 对象尽管是存在堆中,可是在堆栈中依旧存放其堆中地址,因此。...时候也是一样) 那么,创建其对象数组时:A a[2],是否会调用其构造函数呢。这是肯定。...顺序似乎弄错了,郁闷。 还没收到面试信息。也还没有受到笔试挂了通知,也不知道是个什么情况啊。 保持。 有时,细节很重要!

67710

C++核心准则C.35:基函数要么是公开函数,要么是保护非虚函数

C.35: A base class destructor should be either public and virtual, or protected and nonvirtual 基函数要么是公开函数...为了避免无定义行为。如果函数是公有的,那么调用侧代码就会尝试使用基指针销毁派生对象,在基函数为非虚函数时其结果时没有定义。...如果函数时保护,那么调用侧代码就无法通过基类型指针销毁派生对象,这是函数就没有必要一定是虚函数函数是保护而不是私有的,这样派生函数才能调用它。...通常,基设计者不会知道在函数中应该执行什么样动作。...我们可以想象一种需要保护函数函数情况:当希望允许派生对象(只有这个类型)通过基指针销毁另外一个对象(不是它自己)时。但是我们还没有在实际开发中遇到这种情况。

1K20

C++核心准则C.30:如果一个需要明确销毁动作,定义函数

函数在对象生命周期结束时被隐式调用。如果默认函数已经足够,没有必要另外定义。只有在一个需要其成员函数处理之外动作时定义非默认函数。...管理资源没有表现为包含函数。例如vector或者事务。...默认函数可以做得更好,更有效,还不会有错。...如果需要默认函数,但是其产生已经被抑制(例如由于定义了移动构造函数),使用=default(明确要求生成,译者注)。...寻找可能“隐式资源”,例如指针和引用。寻找有函数,即使它们所有的数据成员都有函数

34410

C++】泛型编程 ⑬ ( 模板示例 - 数组模板 | 构造函数函数 声明与实现 | 普通成员函数 声明与实现 | 外部友元函数 声明与实现 )

{ private: // 数组长度 int m_length; // 指向数组数据内存 指针 // 指针类型 是 泛型类型 T T* m_space; }; 2、构造函数函数 ...声明与实现 在声明时 , 前面加上 模板类型声明 template , 说明在中要使用类型 T ; 在 Array 中 , 声明 构造函数 , 拷贝构造函数 , 函数..., 不需要 显示注明 类型 T ; 声明 构造函数 , 拷贝构造函数 , 函数 : template class Array { public: // 有参构造函数...函数 : 在 模板 外部 访问 模板 中声明 函数 , 先显示声明 模板类型 template , 然后在下面使用 域作用符 访问 模板中 函数 , 域作用符...cout << " 调用函数 " << endl; } 3、普通成员函数 声明与实现 重载 数组下标 [] 操作符 , 使用 模板内部 成员函数即可完成 ; 普通成员函数 声明 : 数组下标

37810

C++核心准则​讨论:将基函数设为公共和虚拟,或受保护和非虚拟

函数应该是虚函数吗?也就是说,是否应该允许通过指向基指针进行销毁?如果是,则base函数必须是公共才能被调用,否则虚拟调用它会导致未定义行为。...否则,应该对其进行保护,以便只有派生才能在自己函数中调用它,这个函数也应该是非虚,因为它不需要虚拟地运行。...这种情况导致较早编码标准对所有基函数都必须是虚拟提出了全面的要求。这太过分了(即使是常见情况);相反,规则应该是当且仅当基函数是公共时,才将它们虚函数化。...B是可以自己实例化和具体,因此函数必须是公共,才能创建和销毁B对象。...然后,即使函数必须是公共,也可能会面临很大,不将其虚函数压力,因为作为第一个虚拟函数,当永远不需要添加功能时,它将招致所有运行时类型开销。

1.1K20
领券