You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

C++构造函数内显式构造类成员时是否会调用默认构造函数

C++ 构造时序相关问题解答

你提供的示例代码如下:

class MyClass{
    public:
        MyClass(){
            // do other stuff
            *oc = OtherClass(params);
        }
    private:
        OtherClass* oc;
}

针对你的几个疑问,逐一解答如下:

构造函数调用时序说明

  • 执行到构造函数内// do other stuff代码段时,不存在任何已构造的OtherClass对象,你猜测的“初始化阶段先调用OtherClass默认构造、进入构造函数后再重新赋值”的情况完全不会发生。
  • 原因很简单:oc是指针类型的成员变量,属于内置类型,如果你没有在构造函数初始化列表里给它显式赋值,进入构造函数体时它的值是随机的野指针,没有指向任何合法的OtherClass实例,自然不会触发OtherClass的任何构造逻辑。
  • 代码里*oc = OtherClass(params);这一行确实会调用OtherClass的带参构造,生成一个临时的OtherClass对象,但紧接着你解引用了野指针,尝试把临时对象赋值给野指针指向的非法内存地址——这是典型的未定义行为,运行时大概率直接崩溃,根本不是给合法存在的对象重新赋值。

OtherClass无默认构造时的表现

  • 就你贴的这段错误代码而言,不会触发编译错误:因为你全程没有在合法内存位置构造OtherClass对象,编译器不会检查你对OtherClass构造函数的调用。但代码运行时必然触发内存错误,没有实际可运行性。
  • 如果你本来想写的成员是对象实例而非指针(即OtherClass oc;),又没有在构造函数初始化列表里显式调用OtherClass的带参构造,编译器才会报编译错误:它会在成员初始化阶段尝试调用OtherClass的默认构造,找不到对应实现就会终止编译。
  • 如果你确实需要用指针持有OtherClass实例,正确写法是在构造函数初始化列表里给指针分配合法内存,比如MyClass() : oc(new OtherClass(params)) { /* do other stuff */ },这种场景下哪怕OtherClass没有默认构造,只要传入参数匹配带参构造的签名,就能正常编译运行。

成员定义处直接构造对象的实践建议

  • 对于非指针类型的对象成员,C++11及之后的标准支持在成员声明时直接写初始化逻辑,比如OtherClass oc{params};,这是被广泛认可的良好实践:如果类的多个构造函数都需要用相同参数初始化这个成员,这种写法可以减少初始化列表的重复代码,也能避免成员遗漏初始化的问题。
  • 对于裸指针类型的成员,绝对不要在声明处直接写new OtherClass(params)初始化:裸指针需要手动管理内存释放,非常容易引发内存泄漏、重复释放的问题。如果需要指针语义的成员,优先使用std::unique_ptr、std::shared_ptr这类智能指针,在声明处或者构造函数初始化列表里构造即可,生命周期会被自动管理。
  • 额外提示:你当前示例里解引用未初始化指针的写法是严重错误,任何生产场景下都不能这么写,指针解引用前必须确保它指向已经合法分配的内存。

内容的提问来源于stack exchange,提问作者user16541120

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.30 00:33:23