FEATURED · 精选文章

【C++ 面试真题】聊聊 C++ 的构造与析构

发布时间 / 2026/8/14 5:17:06
来源 / 创域科博编辑部
栏目 / 资讯中心
【C++ 面试真题】聊聊 C++ 的构造与析构 【C 面试真题】聊聊 C 的构造与析构构造和析构是 C 面向对象篇的开场必问。背得出构造初始化、析构清理只是及格真考你的是多层继承下构造析构的执行顺序、基类析构为什么必须 virtual、构造函数里能不能调虚函数——一道题能从语法问到内存布局。本文把构造析构的通用机制一次讲透——它是整个面向对象的地基。一、先说结论构造/析构 对象的生与死❓ 构造函数和析构函数到底是干嘛的✅ 一句话构造函数让对象活过来成员拿到合法初值、申请资源析构函数让对象干净地走释放资源、归还系统。两者都是特殊成员函数——名字固定、没有返回值、你不调编译器替你调structFile{File(constchar*path);// 构造打开文件~File();// 析构关闭文件private:FILE*fp_;};{Filef(a.txt);// 构造自动调用// ... 用 f}// 离开作用域析构自动调用 这就是RAII的根基把资源绑定到对象生命周期构造获取、析构释放再也不用手动 close/free。智能指针、内存管理用的都是这个思想。二、构造函数家族有哪些❓ 构造函数分几种✅ 主要四种本篇聚焦前两种的通用机制拷贝和移动各有专门考法先不展开种类签名特征默认构造无参T()有参构造T(args)拷贝构造T(const T)移动构造T(T)structWidget{Widget();// 默认构造Widget(intn);// 有参构造Widget(constWidget);// 拷贝构造Widget(Widget);// 移动构造};⚠️注意一旦你写了任何一个构造函数编译器就不再为你合成默认构造了。想保留默认构造得显式写Widget() default;。三、构造与析构的执行顺序高频考点❓ 多层继承、成员对象都有构造析构时到底按什么顺序执行✅ 记住一条铁律构造基类先 → 成员对象次 → 自己的函数体最后析构完全相反函数体先 → 成员次 → 基类最后。structMember{Member(){coutMember 构造\n;}~Member(){coutMember 析构\n;}};structBase{Base(){coutBase 构造\n;}~Base(){coutBase 析构\n;}};structMid:Base{// 中间层Mid(){coutMid 构造\n;}~Mid(){coutMid 析构\n;}};structDer:Mid{Member m_;// 成员对象Der(){coutDer 构造\n;}~Der(){coutDer 析构\n;}};{Der d;}// 输出顺序// Base 构造// Mid 构造// Member 构造// Der 构造// Der 析构// Member 析构// Mid 析构// Base 析构记忆窍门构造像穿衣内衣→外套从里到外析构像脱衣外套→内衣从外到里。派生类永远裹在基类外面所以构造最后到位、析构最先脱掉。四、为什么基类析构要 virtual重头戏❓ 为什么总有人说基类析构函数必须声明为 virtual✅ 因为通过基类指针 delete 派生类对象时只有基类析构是 virtual才会触发派生类析构——否则只调基类析构派生部分直接泄漏。看这个经典翻车现场structBase{~Base(){}// ❌ 非 virtual};structDer:Base{int*p_;Der():p_(newint[100]){}~Der(){delete[]p_;}// 不会执行};Base*bnewDer;deleteb;// ❌ 只调 Base::~Base()// Der::~Der() 没被调用// 100 个 int 泄漏加上virtual立刻修好structBase{virtual~Base(){}// ✅ 虚析构};// 现在 delete b 会先调 Der::~Der()// 再调 Base::~Base()顺序正确⚠️判断准则只要这个类打算被多态使用即有人会用基类指针/引用指向派生对象它的析构就必须 virtual。反过来如果一个类不打算被继承或只用具体类型操作析构非 virtual 即可省掉虚表开销。加分点C 核心准则C.35的建议更干脆——一个要有虚函数的类析构基本上就该是 virtual。因为有虚函数本身就是打算被多态使用的信号。这条几乎可以当公式记。五、构造/析构里能调虚函数吗❓ 在构造函数或析构函数里调用虚函数会发生什么✅能编译通过但行为和你想的多态不一样——构造/析构期间虚调用会退化成静态调用只调当前层自己的版本不会进入派生类。structBase{Base(){init();}// ⚠ 调虚函数virtualvoidinit(){coutBase::init;}};structDer:Base{voidinit()override{coutDer::init;}};Der d;// 你以为打印 Der::init// 其实打印 Base::init 为什么构造Der时先执行Base的构造体——此时Der还没成形它的成员还没初始化。如果这时候真的去调Der::init访问到的是一堆垃圾。所以语言规定基类构造期间对象的实际类型就是基类虚函数只能落到基类版本。析构同理拆除顺序里派生部分已经没了。最佳实践别在构造/析构里调虚函数那是 bug 的温床。如果非要在构造期做派生类相关的初始化让派生类自己构造函数里调一次普通虚函数即可——那时对象已完整。虚函数到底是怎么知道该调哪个版本的答案是虚函数表vtable——这是虚函数那道题的核心本文先点到为止。六、 default和 deleteC11❓ default和 delete是干嘛的✅ 两个 C11 引入的显式控制特殊成员函数的语法structWidget{Widget()default;// 显式要默认构造Widget(constWidget)delete;// 禁止拷贝}; default让编译器重新合成那个被你写别的构造函数压制掉的默认实现 delete明确禁用某个函数任何人调用都编译报错。Widget w1;// ✅Widgetw2(w1);// ❌ 编译报错已删除Widget w3w1;// ❌ 同上典型场景不可拷贝的类如std::mutex、std::unique_ptr就是把拷贝构造/拷贝赋值 delete。比 C98 时代声明成 private 且不实现干净得多。七、成员初始化列表为什么要用❓ 为什么推荐用初始化列表而不是在构造体里赋值✅ 因为初始化列表是直接构造成员而在构造体里x 1是先默认构造、再赋值——对成员多了一次默认构造开销而且有些类型const、引用、无默认构造的类只能初始化、不能赋值。structBad{intn;string s;Bad(intx,string str){nx;// 先默认构造再赋值sstr;// 多一次临时对象}};structGood{intn;string s;Good(intx,string str):n(x),s(str){}// ✅ 直接构造};⚠️初始化顺序陷阱成员按声明顺序初始化跟列表里写的顺序无关。如果成员间有依赖搞错声明顺序会用到没初始化的成员structTrap{inta_,b_;// 想让 b a 1Trap(intv):b_(v1),a_(v){}// ⚠ 危险// 实际顺序a_ 先vb_ 后v1// 这里碰巧对但若写成 b_(a_1)// a_ 还是垃圾值};建议成员声明顺序和初始化列表顺序保持一致开-Wreorder警告GCC/Clang 默认开帮你抓这种坑。八、面试高频追问❓ Q1构造函数能是虚函数吗✅不能。虚函数靠虚表工作而虚表指针是在构造期间才被填进去的——构造函数执行时对象还没活没有虚表可用。语言层面直接禁止 virtual 构造函数。❓ Q2析构函数能是纯虚函数吗✅能常用来定义抽象类但必须给纯虚析构提供一份定义否则链接报错——派生类析构时会调用基类析构找不到实现就炸。structBase{virtual~Base()0;// 纯虚析构};Base::~Base(){}// ✅ 必须有定义❓ Q3编译器什么时候会合成默认构造函数✅ 仅当你需要它、又没自己写时比如定义了对象却没给初值。如果类里有成员本身没有默认构造合成会失败。别把会合成当默认保证——需要就显式写。❓ Q4为什么析构函数执行后对象就不能用了✅ 析构一旦执行对象的成员已被销毁、资源已归还再访问就是未定义行为use after free。这也是为什么不要返回局部对象的引用/指针——对象早就没了。❓ Q5构造抛异常会怎样✅已构造的成员和基类子对象会被逆序析构但对象自己的析构不会执行它根本没构造完成。所以在构造里申请多个资源很危险推荐用智能指针成员托管——每个成员自己 RAII异常时自动释放这也是内存管理的核心思想。九、总结速查表考点一句话结论构造顺序基类 → 成员 → 函数体析构顺序函数体 → 成员 → 基类相反多态基类析构必须 virtual否则派生部分泄漏构造期调虚函数退化为静态调用别这么干 default重新要编译器合成 delete明确禁用某函数初始化列表直接构造省开销顺序按声明纯虚析构可以但必须给定义一句话回顾构造是基类→成员→自己析构恰好反过来只要类会被多态使用基类析构就得 virtual——这两条记牢构造析构这一关基本就过了。如果您觉得本篇内容对你有帮助欢迎点赞 、收藏 ⭐、转发 。下期我们继续聊面向对象篇的拷贝构造与拷贝赋值——浅拷贝为什么会 double free、三五法则到底在说什么敬请关注
RELATED — 相关阅读

相关资讯

LATEST — 最新资讯

最新发布

TODAY — 本日精选

新闻

WEEKLY — 本周精选

新闻

MONTHLY — 本月精选

新闻