深度探索C++对象模型--------默认构造函数

简介:

一:默认构造函数的构建

     默认构造函数总是在被需要的时候构建出来!!关键字“被需要的时候”!!


class Foo
{
public:
   int val;
   Foo *next;
};
 
void foo_bar()
{
    Foo bar;
    if(bar.val || bar.next)
        //do something           
}

  上述的代码,编写者意图对象bar中的data member val 和 next 为0。但是编译器没有义务为你初始化为。首先对于堆栈中的变量都不一定会被初始化为0,而是上一次使用的痕迹。

        对于Class Foo,如果没有任何的user-declared constructor,那么就会有一个default constructor被暗中声明出来,而一个被暗中声明出来的构造函数将是一个无用的构造函数,所以上面的代码休想正确运行。

        所以,在生命class Foo对象bar的时候,编译器确实会隐性的声明默认构造函数,但是这个构造函数是无用的。只有在四种情况下,才会生成有用(nontrival default constructor)的构造函数。

   1: 带有"Default Constructor" Member class object。

         如果一个class没有任何的constructor,但是包含的member object 确有default construct,那么编译器为这个class隐形生成的构造函数将是nontrival即有用的,并且会在需要的时候调用发生。

   2: 带有"Default Constructor" 的 Class Base

         如果一个derived class没有任何constructor,但是继承自一个有default constructor的base class,那么这个derived class的构造函数将会是有用的,并且在被需要的时候生成出来,依照继承顺序调用基类的构造函数。

   3: 带有一个"virtual function“ 的 Class


class Widget
{
public:
    virtual int flip() = 0;
    //..
};

void flip(const Widget* widget )
{
    widget->flip();
}

void main()
{
   Bell bell;
   Whistle w;
   flip(bell);
   flip(w);
}

       上述代码中,class Bell 和 Whistle均继承自Widget,在声明bell 和 w的时候,编译器隐形生成的默认构造函数会被调用。因为在基类Widget中有virtual function ,所有带Widget的对象模型中会有指向virtual table 的地址;而在子类class Bell和 Whistle总,这个指针同样需要被制定。

   4: 带有一个“virtual base class” 的Class 

         对于不同的编译器,virtual base class在derived class object中的实现方式差别很大;但是共同点是virtual base class 必须在 derived class object 中的位置,能够在执行期间安置妥当,例如下面的代码:


class X { public int x; };
class A:public virtual X{public int j;};
class B:public virtual X{public float k;}
class C:public A,public B{public float g;};

//无法在编译期间确定x的位置
void foo(const A* pa)
{
     pa->x = 1024;
} 

void main()
{
    foo(new B);
    foo(new C);
}

      为了在运行期间确定x的位置,我们必须做延迟处理:

     void foo(const A* pa)    {   pa->_vbcX->x = 1024;   }    

     其中_vbcX 即是只想virtual base class的指针, 正如你所想的_vbcX正是在构造函数被调用的时候制定的。所以对于没有默认构造函数的带有virtual base class的class object,编译器会在隐性生成的构造函数中指定!


相关文章
|
8月前
|
编译器 C++ 开发者
【C++篇】深度解析类与对象(下)
在上一篇博客中,我们学习了C++的基础类与对象概念,包括类的定义、对象的使用和构造函数的作用。在这一篇,我们将深入探讨C++类的一些重要特性,如构造函数的高级用法、类型转换、static成员、友元、内部类、匿名对象,以及对象拷贝优化等。这些内容可以帮助你更好地理解和应用面向对象编程的核心理念,提升代码的健壮性、灵活性和可维护性。
|
8月前
|
编译器 C语言 C++
类和对象的简述(c++篇)
类和对象的简述(c++篇)
|
7月前
|
编译器 C++
类和对象(中 )C++
本文详细讲解了C++中的默认成员函数,包括构造函数、析构函数、拷贝构造函数、赋值运算符重载和取地址运算符重载等内容。重点分析了各函数的特点、使用场景及相互关系,如构造函数的主要任务是初始化对象,而非创建空间;析构函数用于清理资源;拷贝构造与赋值运算符的区别在于前者用于创建新对象,后者用于已存在的对象赋值。同时,文章还探讨了运算符重载的规则及其应用场景,并通过实例加深理解。最后强调,若类中存在资源管理,需显式定义拷贝构造和赋值运算符以避免浅拷贝问题。
|
7月前
|
存储 编译器 C++
类和对象(上)(C++)
本篇内容主要讲解了C++中类的相关知识,包括类的定义、实例化及this指针的作用。详细说明了类的定义格式、成员函数默认为inline、访问限定符(public、protected、private)的使用规则,以及class与struct的区别。同时分析了类实例化的概念,对象大小的计算规则和内存对齐原则。最后介绍了this指针的工作机制,解释了成员函数如何通过隐含的this指针区分不同对象的数据。这些知识点帮助我们更好地理解C++中类的封装性和对象的实现原理。
|
7月前
|
编译器 C++
类和对象(下)C++
本内容主要讲解C++中的初始化列表、类型转换、静态成员、友元、内部类、匿名对象及对象拷贝时的编译器优化。初始化列表用于成员变量定义初始化,尤其对引用、const及无默认构造函数的类类型变量至关重要。类型转换中,`explicit`可禁用隐式转换。静态成员属类而非对象,受访问限定符约束。内部类是独立类,可增强封装性。匿名对象生命周期短,常用于临时场景。编译器会优化对象拷贝以提高效率。最后,鼓励大家通过重复练习提升技能!
|
9月前
|
C++ 芯片
【C++面向对象——类与对象】Computer类(头歌实践教学平台习题)【合集】
声明一个简单的Computer类,含有数据成员芯片(cpu)、内存(ram)、光驱(cdrom)等等,以及两个公有成员函数run、stop。只能在类的内部访问。这是一种数据隐藏的机制,用于保护类的数据不被外部随意修改。根据提示,在右侧编辑器补充代码,平台会对你编写的代码进行测试。成员可以在派生类(继承该类的子类)中访问。成员,在类的外部不能直接访问。可以在类的外部直接访问。为了完成本关任务,你需要掌握。
187 19
|
9月前
|
存储 编译器 数据安全/隐私保护
【C++面向对象——类与对象】CPU类(头歌实践教学平台习题)【合集】
声明一个CPU类,包含等级(rank)、频率(frequency)、电压(voltage)等属性,以及两个公有成员函数run、stop。根据提示,在右侧编辑器补充代码,平台会对你编写的代码进行测试。​ 相关知识 类的声明和使用。 类的声明和对象的声明。 构造函数和析构函数的执行。 一、类的声明和使用 1.类的声明基础 在C++中,类是创建对象的蓝图。类的声明定义了类的成员,包括数据成员(变量)和成员函数(方法)。一个简单的类声明示例如下: classMyClass{ public: int
262 13
|
8月前
|
安全 编译器 C语言
【C++篇】深度解析类与对象(中)
在上一篇博客中,我们学习了C++类与对象的基础内容。这一次,我们将深入探讨C++类的关键特性,包括构造函数、析构函数、拷贝构造函数、赋值运算符重载、以及取地址运算符的重载。这些内容是理解面向对象编程的关键,也帮助我们更好地掌握C++内存管理的细节和编码的高级技巧。
|
8月前
|
存储 程序员 C语言
【C++篇】深度解析类与对象(上)
在C++中,类和对象是面向对象编程的基础组成部分。通过类,程序员可以对现实世界的实体进行模拟和抽象。类的基本概念包括成员变量、成员函数、访问控制等。本篇博客将介绍C++类与对象的基础知识,为后续学习打下良好的基础。
|
10月前
|
机器学习/深度学习 人工智能 自然语言处理
C++构建 GAN 模型:生成器与判别器平衡训练的关键秘籍
生成对抗网络(GAN)是AI领域的明星,尤其在C++中构建时,平衡生成器与判别器的训练尤为关键。本文探讨了GAN的基本架构、训练原理及平衡训练的重要性,提出了包括合理初始化、精心设计损失函数、动态调整学习率、引入正则化技术和监测训练过程在内的五大策略,旨在确保GAN模型在C++环境下的高效、稳定训练,以生成高质量的结果,推动AI技术的发展。
316 10