默认构造函数的生成时机

2021-08-21  本文已影响0人  404Not_Found

默认构造函数不是每次都生成的

默认构造函数并不是每次都生成的。以下述代码为例 同时开发环境为
vs2017

对象作为类成员

class MATX
{
public:
};

class MBTX
{
public:
    int m_i;
    int m_j;
    void funct()
    {
        cout << "euaihls" << endl;
    }
};

int main(int argc, char ** argv)
{
    MBTX myb;
    return 0;
}

生成项目
打开 vs2017 开发人员命令提示符
进入项目的DEBUG路径
输入

dumpbin /all main.obn > my.txt

拖到vs2017里。 搜索 MBTX::MBTX 没有任何信息

默认构造函数生成时机

class MATX
{
public:
    MATX()
    {
        cout << "euaihlsMATX" << endl;
    }
};

class MBTX
{
public:
    int m_i;
    int m_j;
    void funct()
    {
        cout << "euaihls" << endl;
    }
    MATX ma;
};

int main(int argc, char ** argv)
{
    MBTX myb;
    return 0;
} 
  1. MATX 有默认构造函数 MBTX 没够构造函数,则 MBTX会生成默认构造函数,合成的目的是调用MATX, 并且在 MBTX中安插代码,用来调用 MATX::MATX() 构造函数.
    MBTX(默认生成) 调用 MATX构造函数.png

子类无构造函数,父类有构造函数

子类和父类之间的构造函数生成关系如下:
子类无默认构造函数,父类有默认构造函数,编译器会为子类合成一个默认构造函数

class MATX
{
public:
    MATX()
    {
        cout << "euaihlsMATX" << endl;
    }
};

class MBTXParent
{
public:
    MBTXParent()
    {
        cout << "MBTXPARENT()" << endl;
    }

};

class MBTX: public MBTXParent
{
public:
    int m_i;
    int m_j;
    void funct()
    {
        cout << "euaihls" << endl;
    }
};

int main(int argc, char ** argv)
{
    MBTX myb;
    return 0;
}
结果.png

默认生成的子类构造函数中,会调用父类构造函数

带有虚函数的类

因为虚函数的存在,就注定会有虚函数表,构造函数中的动作:
把虚函数表地址赋值给对象中的 vptr。

class MBTX
{
public:
    int m_i;
    int m_j;

    //可以看下 构造函数中额外的新增代码
    MBTX()
    {
        m_i = 15;
    }
    
    virtual void mvirfunc()
    {
        cout << "mvirfunc" << endl;
    }

    void funct()
    {
        cout << "euaihls" << endl;
    }
};

int main(int argc, char ** argv)
{
    MBTX myb;
    return 0;
}
构造函数中的vftable.png

虚函数表的位置:


vftable.png

在vs2017 反汇编中的代码


对vftable 进行赋值.png

虚基类

钻石结构.png

虚基类结构:Grand 无构造函数, Father A, Father A2 无构造函数
Son C 无构造函数。
则在创建 Son C 中 会默认给 C A A2 合成默认构造函数

class Grand
{
public:
};

class A : virtual public Grand
{
public:
};

class A2 : virtual public Grand
{
public:

};

class C : public A, public A2
{
public:

};

int main(int argc, char ** argv)
{
    C cc;
    return 0;
}

vbtable 虚基类的表:
默认的构造函数,A, A2 分别存有 一个 vbtable。
类似这种


vbtable.png

C 中的结构


C的结构.png

虚基类了解到此即可,后续有机会深入研究再谈。

上一篇 下一篇

猜你喜欢

热点阅读