c++ 对象模型3

本文深入探讨C++中构造函数的合成条件,包括默认构造函数的生成时机、类成员和继承关系对构造函数合成的影响,以及虚函数和虚基类的作用。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

一 : 分析obj(目标文件) 构造函数语义
    1.构造函数: 默认构造函数(缺省构造函数) ; 没有参数的构造函数
    2.如果我们没有定义任何构造函数,那么编译器就会为我们默认隐式自动定义一个构造函数(合成的构造函数
    3.但是这种合成默认构造函数 只有在必要的时候 编译器才合成出来,而不是必须为我们合成出来。

二 : 什么时候才是必要时候
    1.每个.cpp源文件会编译生成一个.obj(linux gcc -c .o)  ,最终把很多.obj(.o) 文件链接到一起生成一个可执行文件。
    
    2.先生成一段obj 然后通过VS自带的工具 开发人员命令提示符(Developer Command Prompr) 调试obj
    
    class A{
    public:
    
    }
    class B{
    public:
        int a;
        int b;
        void func(){
            cout << "IAMVeryGood" <<endl;
        }
    }
    int main(){
        B b;
    }
    
    3.ctrl b 这个文件然后我们打开生成的Debug文件找到和.cpp同名的.obj文件  然后我们使用上面提到的工具进入到debug中目录
    4.dumpbin /all project100.obj > my.txt 
    5.我们CTRL F查找我们希望编译器为我们生成的 B::B(); 但是没有。
    6.所以这种情况 编译器不会为我们生成对应的构造函数

二: 修改代码
    class A{
    public:
        A(){};  // 默认构造函数
    }
    class B{
    public:
        int a;
        int b;
        A a;
        void func(){
            cout << "IAMVeryGood" <<endl;
        }
    }
    int main(){
        B b;
    }
    // 类B没有任何构造函数, 但是包含一个类类型的成员a, 而该对象所属类A 有一个缺省的构造函数
    // 这个时候编译器就会给类B生成一个 "合成默认的构造函数", 这个合成构造函数的目的是调用A的构造函数
    // 也就是编译器合成了类B的构造函数,并在其中 安插代码,调用类Ad额缺省构造函数
    // 我们可以重复上述命令行操作 找到B::B();

三:第三种情况
    1. 父类带有缺省构造函数,子类没有任何构造函数,那么父类这个缺省构造函数要被调用,所以编译器会为子类合成一个默认构造函数
    2. 合成的目的: 调用父类的构造函数
    class A{
    public:
        A(){};  // 默认构造函数
    }
    class B : public A{
    public:
        int a;
        int b;
        void func(){
            cout << "IAMVeryGood" <<endl;
        }
    }
    int main(){
        B b;  // 找生成的构造函数操作如上
    }

四: 第四种情况
    1. 如果一个类还有虚函数,但没有任何构造函数时候。
    class B{
    public:
        int a;
        int b;
        void func(){
            cout << "IAMVeryGood" <<endl;
        }
        virtual void viritualFunc(){
            cout << "viritualFunc" <<endl;
        }
    }
    // 因为有虚函数,所以编译器会合成一个构造函数,生成一个基于该类的虚函数表 (vftable( my.txt 可以找到
        // ( 大约在2459行 :  ...   const B::`vftable‘  这么个东西
    // 然后把该类的虚函数表地址赋给类对象的虚函数指针 (赋值语句)
    // 虚函数表的主要作用就是为了搞搞多态
    // 当然 如果写了构造函数,则会给构造函数添加相应的虚函数表操作的代码

五: 第五种情况
    1.如果一个类带有虚基类,编译器也会为它合成一个默认构造函数
    class Grand(){
    public:
    }
    class A : virtual public Grand{  // 有构造函数 (vbtable  虚基类表 和虚函数表不是一个东西
    public:
    }
    class B : virtual public Grand{  // 有构造函数 (vbtable  虚基类表
    public:
    }
    class C : public A, public B{  // 虚基类表首地址
    public:
    
    }
    int main(){
        C c;
    }

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值