`
蒙面考拉
  • 浏览: 160244 次
  • 性别: Icon_minigender_1
  • 来自: 深圳
社区版块
存档分类
最新评论

C++类对象的创建过程

 
阅读更多

分配空间(Allocation)
        创建C++类对象的第一步就是为其分配内存空间。对于全局对象,静态对象以及分配在栈区域内的对象,对它们的内存分配是在编译阶段就完成了,而对于分配在堆区域内的对象,它们的分配是在运行是动态进行的内存空间的分配过程涉及到两个关键的问题:
需要分配空间的大小,即类对象的大小。这么问题对于编译器来说并不是什么问题,因为类对象的大小就是由它决定的,对于要分配多少内存,它最清楚不过了。

         是否有足够的内存空间来满足分配。对于不同的情况我们需要具体问题具体分析:局对象和静态对象。编译器会为他们划分一个独立的段(全局段)为他们分配足够的空间,一般不会涉及到内存空间不够的问题
           分配在栈区域的对象。栈区域的大小由编译器的设置决定,不管具体的设置怎样,总归它是有一个具体的值,所以栈空间是有限的,在栈区域内同时分配超过空间大小的对象会导致栈区域溢出,由于栈区域的分配是在编译阶段完成的,所以在栈区域溢出的时候会抛出编译阶段的异常。

           分配在堆区域的对象。堆内存空间的分配是在运行是进行的,由于堆空间也是有限的,在栈区域内试图同时分配大量的对象会导致分配失败,通常情况会抛出运行时异常或者返回一个没有意义的值(通常是0)。

 

初始化(Initialization)
           这一阶段是对象创建过程中最神秘的一个阶段,也是最容易被忽视的一个阶段。要想知道这一阶段具体完成那些任务,关键是要区分两个容易混淆的概念:初始化 (Initialization)和赋值(Assignment)。初始化早于赋值,它是随着对象的诞生一起进行的。而赋值是在对象诞生以后又给予它一个新的值。这里我想到了一个很好的例子:任何一个在医院诞生的婴儿,在它诞生的同时医院会给它一个标识,以防止和其他的婴儿混淆,这个标识通常是婴儿母亲所在床铺的编号,医院给婴儿一个标识的过程可以看作是初始化。当然当婴儿的父母拿到他们会为他们起个名字,起名字的过程就可以看作是赋值经过初始化和赋值后,其他人就可以通过名字来标识他们的身份了。区分了这两个概念后,我们再转到对对象初始化的分析上。对类对象的初始化,实际上是对类对象内的所有数据成员进行初始化。C++已经为我们提供了对类对象进行初始化的能力,我们可以通过实现构造函数的初始化列表(member initialization list)来实现。具体的情况是否是这样的呢?下面我们就看看具体的情况是什么样的吧。我写了两个简单的类:

    class CInnerClass {
    public:
        CInnerClass(int id):m_iID(id) {}
        CInnerClass& operator = (const CInnerClass& rb) {
            m_iID = rb.m_iID;
            return *this;
        }
    private:
        int m_iID;
    };
   
    class CJdBase {
    public:
        CJdBase::CJdBase(int id):m_innerObj(id),m_iID(id){
            m_innerObj = 10;
        }
    private:
        CInnerClass m_innerObj;
        int m_iID;
    };我们重点是看看CJdBase类的构造函数。CJdBase类的构造函数提供了初始化列表,用来初始化其成员变量,其相应的汇编代码如下(注:我只保留了关键的代码):

    mov    DWORD PTR _this$[ebp], ecx
    mov    eax, DWORD PTR _id$[ebp]
    push    eax
    mov    ecx, DWORD PTR _this$[ebp]
    call   
??0CInnerClass@@QAE@H@Z            ; CInnerClass::CInnerClass
    mov    eax, DWORD PTR _this$[ebp]
    mov    ecx, DWORD PTR _id$[ebp]
    mov    DWORD PTR [eax+4], ecx

; 5    :     m_innerObj = 10;

    push    10                    ; 0000000aH
    lea    ecx, DWORD PTR $T1359[ebp]
    call   
??0CInnerClass@@QAE@H@Z            ; CInnerClass::CInnerClass
    lea    eax, DWORD PTR $T1359[ebp]
    push    eax
    mov    ecx, DWORD PTR _this$[ebp]
    call   
??4CInnerClass@@QAEAAV0@ABV0@@Z        ; CInnerClass::operator=

 

从这段汇编代码中我们可以看到一些有意义的内容:

初始化列表先于构造函数体内的代码执行;
初始化列表确实执行的是数据成员的初始化过程,这个可以从成员对象的构造函数被调用看的出来。

赋值(Assignment)
对象经过初始化以后,我们仍然可以对其进行赋值。和类对象的初始化一样,类对象的赋值实际上是对类对象内的所有数据成员进行赋值。C++也已经为我们提供了这样的能力,我们可以通过构造函数的实现体(即构造函数中由"{}"包裹的部分)来实现。这一点也可以从上面的汇编代码中成员对象的赋值操作符 (operator =)被调用得到印证。

结束
随着构造函数执行完最后一行代码,可以说类对象的创建过程也就顺利完成了。由以上的分析可以看出,构造函数实现了对象的初始化和赋值两个过程:
对象的初始化是通过初始化列表来完成,而对象的赋值则才是通过构造函数,或者更准确的说应该是构造函数的实现体

分享到:
评论

相关推荐

    c++面向对象编程实例大全

    - 类的定义与对象创建的实例,如学生信息管理系统。 - 封装概念的实现,如私有化数据成员和公有接口。 - 继承的案例,如不同类型的交通工具从一个基础的`Vehicle`类派生。 - 多态的应用,如设计一个通用的图形库,...

    C++面向对象实验代码实验2

    2. 类(Class)与对象(Object):在C++中,类是模板,用于创建对象。对象是类的实例,它们拥有类定义的所有属性和方法。`test2`可能包含了创建对象并调用其成员函数的代码,以展示如何通过对象来操作数据。 3. ...

    c++类和对象习题答案

    - 对象创建:使用类名和new运算符创建对象,如`Student s1;`或`Student* s2 = new Student();` 2. **访问控制(public, private, protected)** - 公有成员(public):可以直接在类的外部访问。 - 私有成员...

    C++面向对象程序设计教程——课件PPT

    C++是一种强大的编程语言,以其面向对象特性而闻名,它结合了过程化编程和面向对象编程的优势。在“C++面向对象程序设计教程——课件PPT”中,我们可以深入学习这一主题,由陈维兴和林小茶编著,清华大学出版社出版...

    C++面向对象程序设计PDF电子书与参考答案

    2. **类**:类是创建对象的蓝图,定义了一组特性和行为。在C++中,我们通过关键字"class"来声明一个类,并在类中声明变量(数据成员)和函数(成员函数)。 3. **对象**:对象是类的实例,它具有类定义的属性和行为...

    C++类与对象的修改

    在C++中,我们通过`class`关键字来声明一个类,并可以创建类的实例(对象)。 8.3 类的成员函数 类的成员函数(也称为方法)是定义在类内部,用于操作类的属性和执行相关行为的函数。这些函数可以访问类的私有和...

    c++面向对象程序设计课后习题答案

    在C++中,面向对象的核心概念包括类(Class)、对象(Object)、继承(Inheritance)、多态(Polymorphism)和封装(Encapsulation)。以下是对这些概念的详细解释: 1. **类(Class)**:类是面向对象编程的基础,...

    C++面向对象程序设计上机考试题库.pdf

    本题库展示了面向对象程序设计在C++中的实际应用,题目包含了多个具有代表性的C++程序示例,涵盖了类的定义、构造函数、成员函数、私有成员、公有成员、重载构造函数、模板类以及对象的创建和使用等方面的知识。...

    C++动态生成对象

    在C++编程中,动态生成对象是指在程序运行时创建对象,而不是在编译时确定。这通常是通过使用new运算符来实现的。动态生成对象的主要优点是可以在运行时根据需要分配内存,增加代码的灵活性和可扩展性。在描述中提到...

    《C++面向对象程序设计》第2版编程题答案

    在C++中,类是创建对象的蓝图,它定义了对象的状态(数据成员)和行为(成员函数)。构造函数是类的一个特殊函数,用于初始化新创建的对象,而析构函数则在对象生命周期结束时自动调用,用于释放资源。继承是类之间...

    leiheduixiang.rar_C++类对象

    在C++编程语言中,类(Class)是创建对象(Object)的蓝图,它定义了一组属性(数据成员)和行为(成员函数),这些属性和行为共同构成了类的特性。对象则是类的具体实例,它拥有类所定义的属性和行为。本资料...

    c++面向对象程序设计答案 陈维新 林小茶

    C++是一种支持OOP的强类型、静态类型的编程语言,它结合了过程化编程的效率和面向对象编程的灵活性。 1. 类(Class):类是面向对象编程的核心,它是对象的蓝图或模板。一个类定义了一组属性(数据成员)和方法...

    Visual C++ 面向对象编程教程——王育坚

    在《Visual C++ 面向对象编程教程——王育坚》中,你可能会学到如何创建和管理MFC应用程序,如何定义和使用类,以及如何利用MFC的控件库构建用户界面。教程中的例题将帮助你理解如何在实际项目中运用这些概念。例如...

    C++面向对象程序设计_第三版_谭浩强_课后答案[1-14章

    - **继承**:继承允许创建一个新类,这个新类继承了现有类的属性和行为。子类可以继承父类的特性,并扩展新的功能。 - **多态**:多态是指允许不同类的对象对同一消息做出响应的能力。在C++中,多态可以通过虚函数来...

    c++面向对象程序设计语言重点难点复习题及答案.doc

    面向对象程序设计是C++的核心特性之一,它包括类、对象、封装、继承、多态等概念。在C++中,面向对象编程提供了强大的抽象能力,使得程序员可以更有效地管理和组织代码。 首先,我们来看看一些关于C++面向对象的...

    C++面向对象程序设计(第2版)代码

    C++是一种强大的、通用的编程语言,由Bjarne Stroustrup在C语言的基础上发展而来,增加了类、继承、多态等面向对象特性。在《C++面向对象程序设计(第2版)》中,作者详细阐述了这些概念: 1. **基本语法与数据类型...

    c++面向对象程序设计(第2版)

    课件中可能涵盖了C++的基础语法,如变量、运算符、流程控制,然后逐步深入到类和对象的使用,构造函数与析构函数,访问修饰符(public、private、protected),友元,模板,异常处理,STL容器(如vector、list、set...

    贪吃蛇C++源码 C++面向对象实现

    在本项目中,我们主要探讨的是使用C++编程语言,基于面向对象的编程思想来实现经典的小游戏——“贪吃蛇”。贪吃蛇游戏是一种深受玩家喜爱的简单但具有挑战性的游戏,它要求玩家控制一条蛇,通过吃食物来增长长度,...

    C++面向对象程序设计教材ppt

    **C++面向对象程序设计** 是一种强大的编程范式,它允许程序员以类和对象的形式组织和处理数据。本教程的PPT旨在为初学者提供一个深入理解C++面向对象编程概念的基础。以下是对该主题的详细阐述: 1. **类与对象**...

    c++面向对象程序设计例题习题源码

    面向对象编程(Object-Oriented Programming,OOP)是C++的核心,它通过类和对象的概念,实现了代码的封装、继承和多态,极大地提高了软件开发的效率和可维护性。本压缩包包含的是教材中的例题和习题的源码,是学习...

Global site tag (gtag.js) - Google Analytics