构造函数需无返回类型、名同类名、不可用virtual/static/const修饰;析构函数在对象生命周期结束时自动调用,用于清理资源而非释放内存,有虚函数的类应声明虚析构函数。
构造函数怎么写才不会报错
构造函数不是普通函数,它没有返回类型(连
都不能写),名字必须和类名完全一致,且不能被
、
或
修饰。
常见错误现象:
、
。
如果类里没写任何构造函数,编译器会自动生成一个无参、空体的默认构造函数;但只要写了任意一个构造函数,这个自动生成就没了
想同时支持无参和带参初始化,得显式写两个:
和
,否则
会编译失败
推荐用委托构造(C++11 起)避免重复逻辑:
,注意冒号后是调用另一个构造函数,不是函数调用语句
初始化列表比在函数体内赋值更高效,尤其对 const 成员、引用成员或没有默认构造函数的类类型成员——它们只能在初始化列表里“出生”时被赋予初值
析构函数什么时候会被调用
析构函数的作用不是“释放内存”,而是“清理资源”。它在对象生命周期结束时自动调用:局部对象出作用域、
动态分配的对象、临时对象绑定到 const 引用结束后(除非延长了生命周期)。
典型误用:
在析构函数里调用,或者手动调用
—— 这些都会导致重复析构,大概率崩溃。
C知道
CSDN推出的一款AI技术问答工具
下载
立即学习
“
C++免费学习笔记(深入)
”;
析构函数必须是
且非
的;如果类有虚函数,析构函数最好声明为
,否则通过基类指针删除派生类对象时,派生类部分不会被析构
不要在析构函数里抛异常(C++11 起默认是
),否则程序直接终止——因为栈展开过程中再抛异常是未定义行为
析构函数里别调用虚函数,此时虚表可能已被销毁,实际调用的是当前类(而非最终派生类)的版本
移动语义下构造/析构的调用顺序容易被忽略
当对象被移动(比如
扩容时重新安置元素),移动构造函数和移动析构函数参与进来,但它们的行为和拷贝版完全不同:移动构造通常“掏空”源对象,而移动析构对已掏空的对象要能安全收尾。
移动构造函数参数是右值引用:
,内部常做指针交换、置空操作,不 new/malloc 新资源
对应地,析构函数必须能处理“内部指针为
”的状态,否则
虽安全,但
前不判空就危险
若类管理文件描述符、socket、mutex 等系统资源,移动后原对象应标记为“已转移”,析构时跳过关闭逻辑;否则双关、死锁、段错误都可能发生
构造函数和析构函数真正难的不是语法,而是生命周期边界是否清晰——尤其是资源所有权在多个对象间流转时,谁创建、谁释放、谁作废,稍不留神,
或
就藏在看似正常的调用链里。
voidvirtualstaticconsterror: constructor cannot be declared 'virtual'error: return type specified for constructorA()A(int x)A a;A() : A(0) {}deletedelete this;obj.~A()publicstaticvirtualnoexceptstd::vectorA(A&& other)nullptrdelete nullptrdelete ptrdouble freeuse-after-free