C++对象的构造实例分析


这篇“C++对象的构造实例分析”文章的知识点大部分人都不太理解,所以小编给大家总结了以下内容,内容详细,步骤清晰,具有一定的借鉴价值,希望大家阅读完这篇文章能有所收获,下面我们一起来看看这篇“C++对象的构造实例分析”文章吧。问题:对象中成员变量的初始值是多少?下面的类定义中成员变量 i 和 j 的初始值为多少?下面看一段成员变量初始值的代码:下面为输出结果:对象t1 所占用的存储空间在栈上面,而且成员变量 i 和 j 也没有明确的初始值,所以初始值就不定。对象 gt 所占用的存储空间在全局数据区,所以初始值统一为 0。Test* pt = new Test;意味着在堆空间中生成一个 Test 对象,虽然 pt->i 和 pt->j 均为 0,这只是巧合罢了,因为在堆上创建对象时,成员变量初始为随机值。注:类得到的其实是数据类型,所以说通过这种数据类型在全局数据区、栈和堆上面都能够生成对象。从程序设计的角度,对象只是变量,因此:在栈上创建对象时,成员变量初始为随机值在堆上创建对象时,成员变量初始为随机值在静态存储区创建对象时,成员变量初始为 0 值生活中的对象都是在初始化后上市的初始状态(出厂设置)是对象普遍存在的一个状态—股而言,对象都需要—个确定的初始状态解决方案在类中提供一个 public 的 initialize 函数对象创建后立即调用 initialize 函数进行初始化如下:下面看一段初始化函数的代码:下面为输出结果:存在的问题initialize 只是一个普通函数,必须显示调用如果未调用 initialize 函数,运行结果是不确定的下面为解决办法:C++中可以定义与类名相同的特殊成员函数这种特殊的成员函数叫做构造函数构造没有任何返回类型的声明构造函数在对象定义时自动被调用下面来体验一下构造函数:下面为输出结果:可以看到,Test() Begin 和 Test() End 出现了三次,也就是说,Test() 这个构造函数被调用了三次,这是因为创建了三个对象。每个对象在使用之前都应该初始化类的构造函数用于对象的初始化构造函数与类同名并且没有返回值构造函数在对象定义时自动被调用带有参数的构造函数构造函数可以根据需要定义参数一个类中可以存在多个重载的构造函数构造函数的重载遵循 C++ 重载的规则如下:友情提醒对象定义和对象声明不同对象定义–申请对象的空间并调用构造函数对象声明–告诉编译器存在这样一个对象如下:构造函数的自动调用如下:下面看一段带参数的构造函数的代码:下面为输出结果,和预想中的一致。这里需要明确一个问题,int i = 1;与 int i; i = 1;的不同。前者是初始化,后者是先定义,再赋值。后者由于定义 i 时没有初始化,所以 i 的值时随机的。C语言中这两者差别很小,但是在 C++ 中两者差异很大。差别在于在 C++ 中初始化会调用构造函数。下面看一个例子,在上述代码的基础上加一行代码 t = t2;下面为输出结果,可以看到与上面的代码输出结果一模一样。这就因为 C++ 中初始化和赋值不同,初始化会调用构造函数,赋值的时候则不用。下面再看一个例子:下面为输出结果:构造函数的调用一般情况下,构造函数在对象定义时被自动调用—些特殊情况下,需要手工调用构造函数下面看一段构造函数手动调用的代码:下面为输出结果,可以看到,Test(1)、Test(2) 和 Test(100) 均为手动调用构造函数。需求:开发一个数组类解决原生数组的安全性问题提供函数获取数组长度提供函数获取数组元素提供函数设置数组元素IntArray.h:IntArray.cpp:main.cpp:下面为输出结果:这样写出来的数组很安全,没有数组越界问题。构造函数可以根据需要定义参数构造函数之间可以存在重载关系构造函数遵循 C++ 中重载函数的规则对象定义时会触发构造函数的调用在一些情况下可以手动调用构造函数两个特殊的构造函数无参构造函数没有参数的构造函数当类中没有定义构造函数时,编译器默认提供一个无参构造函数,并且其函数体为空拷贝构造函数参数为 const class_name& 的构造函数当类中没有定义拷贝构造函数时,编译器默认提供一个拷贝构造函数,简单的进行成员变量的值复制下面看一段无参数构造函数的代码(代码3-1):可以看到,编译通过:创建一个类的对象必须要调用构造函数,为什么能够编译通过呢?这是因为编译器在发现我们没有定义构造函数时,会默认提供一个无参构造函数,等效如(代码3-2):小贴士:所以说,class T { }; 里面不是什么都没有,里面至少有一个无参构造函数。下面再来看一段代码(代码3-3):下面为输出结果:这里的 i 和 j 打印出来的都是随机值,这是因为类里面没有手工编写的构造函数,所以 t1 和 t2 所采用的就是编译器提供的默认无参构造函数构造的,编译器提供的无参构造函数为空,所以 i 和 j 的值就是随机的。上述代码就相当于(代码3-4):但是编译的时候会报错:这是因为在类里面没有编写任何构造函数时,编译器才提供默认的无参构造函数。这里手工编写了一个拷贝构造函数,编译器就不会提供默认的无参构造函数,需要自己把无参构造函数加上。如下,自己加上无参构造函数(代码3-5):这样就能编译通过了,而且效果跟代码3-3的相同:拷贝构造函数的意义兼容C语言的初始化方式初始化行为能够符合预期的逻辑浅拷贝拷贝后对象的物理状态相同(物理状态指的是对象占据的内存当中每个字节是否相等,如代码3-6)深拷贝拷贝后对象的逻辑状态相同(逻辑状态指的是指针所指向的内存空间的值是否相同,如代码3-9)注:编译器提供的拷贝构造函数只进行浅拷贝!下面看一段代码(代码3-6):下面为输出结果:这段程序的第一个问题就是 t1 和 t2 的 p 指针都指向同一个堆空间中的地址,第二个问题就是申请了内存并没有释放,会造成内存泄漏。下面加上释放内存的代码(代码3-7):下面为输出结果,编译能通过,但是运行时发生了错误,释放了两次堆空间的内存:下面为解决方法(代码3-8):下面为输出结果,可以到 t1 和 t2 的 p 指针分别指向不同的堆空间地址:如果我们看一下逻辑状态,也就是 *t1.p 和 *t2.p 的值,代码如下(代码3-9):下面为输出结果,可以看到 *t1.p 和 *t2.p 的值相同,也就是说逻辑状态相同,这就叫做深拷贝。什么时候需要进行深拷贝?对象中有成员指代了系统中的资源成员指向了动态内存空间成员打开了外存中的文件成员使用了系统中的网络端口……问题分析下面就是浅拷贝:一般性原则自定义拷贝构造函数,必然需要实现深拷贝!!!下面看一个使用深拷贝,对前面数组的代码进行改造。IntArray.h:IntArray.cpp:main.cpp:下面为输出结果:可以看到 b 数组里面的元素与 a 数组里面的元素相同,这就是深拷贝构造函数的结果。以上就是关于免费云主机域名“C++对象的构造实例分析”这篇文章的内容,相信大家都有了一定的了解,希望小编分享的内容对大家有帮助,若想了解更多相关的知识内容,请关注百云主机行业资讯频道。

相关推荐: React中useMemo与useCallback的区别是什么

这篇文章主要介绍“React中useMemo与useCallback的区别是什么”,在日常操作中,相信很多人在React中useMemo与useCallback的区别是什么问题上存在疑惑,小编查阅了各式资料,整理出简单好用的操作方法,希望对大家解答”React…

免责声明:本站发布的图片视频文字,以转载和分享为主,文章观点不代表本站立场,本站不承担相关法律责任;如果涉及侵权请联系邮箱:360163164@qq.com举报,并提供相关证据,经查实将立刻删除涉嫌侵权内容。

Like (0)
Donate 微信扫一扫 微信扫一扫
Previous 04/21 22:06
Next 04/21 22:07

相关推荐