C/C++知识点之构造函数的手动和自动调用方式
从安 2019-06-04 来源 : 阅读 513 评论 0

摘要:本篇文章主要讲述C/C++知识点之构造函数的手动和自动调用方式,希望阅读本篇文章以后大家有所收获,帮助大家对相关内容的理解更加深入。

本篇文章主要讲述C/C++知识点之构造函数的手动和自动调用方式,希望阅读本篇文章以后大家有所收获,帮助大家对相关内容的理解更加深入。

C/C++知识点之构造函数的手动和自动调用方式

一、对象的构造通过构造函数来完成,和类名相同且没有返回值,这个时候只有参数一个特性,构造函数可以自定义参数,这个参数一般而言就是对类进行初始  化来使用的;带有参数的构造函数的意义在于可以使得每个对象有不同的初始化状态(生活中每个事物必然包含自己的初始化状态,不如人的出生,面向对象用来将生活中的事物映射的程序设计领域,所以现实世界的情况都必须可以用面向对象的语言来描述,因此带有参数的构造函数就是非常必要的);

 

二、带有参数的构造函数:

    1,构造函数可以根据需要定义参数;

    2,一个类中可以存在多个重载的构造函数;

    3,构造函数的重载遵循 C++ 重载的规则;

代码示例:

1 class Test
2 {
3 public:
4     Test(int v)
5     {
6         // use v to initialize member
7     }
8 };


三、对象定义和对象声明的区别:

(一)对象定义:申请对象的空间并调用构造函数;

       1,第一步,必须申请对象所占用的内存空间;

       2,第二步,调用构造函数;

(二)对象声明:告诉编译器存在这样一个对象;

       1,对象在哪里定义的不知道,链接的时候回去找;

       2,预处理,编译器对源代码进行检查并生成目标文件,链接器在各个目标文件中寻找目标文件存在的一些名字;

       3,对象声明时,没有对象定义时的两个步骤;

代码示例:

1 Test t;  // 定义对象并调用构造函数;
2 
3 Int main()
4 {
5     // 告诉编译器存在名为 t 的Test对象;
6     extern Test t;
7 
8     return 0;
9 }

        4,对象的声明中可以在构造函数参数中给出默认值,对象的定义中不能够在构 造函数参数中给出默认值;

   

四、构造函数的自动调用(第一种初始化对象方式):

1 #include 2 
3 class Test
4 {
5 public:
6     Test() 
7     { 
8         printf("Test()\n");
9     }
10     
11     Test(int v) 
12     { 
13         printf("Test(int v), v = %d\n", v);
14     }
15 };
16 
17 int main()
18 {
19     Test t;      // 调用 Test()
20     Test t1(1);  // 初始胡第一种方式的参数式自动调用,调用 Test(int v);这里也是定义对象,看上去非常像函数调用,但是这里是告诉编译器要调用带有参数的函数,由重载规则确定调用的是那个构造函数;
21     Test t2 = 2; // 初始化第一种方式的赋值式自动调用,调用 Test(int v);C 语言中初始化的方法,定义一个变量后,立即指明一个值,通过赋值符号指明;这在面向对象中其实也是对象的定义,并且指明想用右值初始化左值;
22  
23     t = t2;  // 这是赋值操作,这里运行后不会调用构造函数,没有打印语句;初始化会调用构造函数,赋值则看后续课程;
24  
25     int i = 1;  // 用 1 对 i 进行初始化;
26     i = 1;  // 用 1 对 i 进行赋值;赋值和初始化是不同的;在面向对象当中,不同在于初始化是要调用构造函数的;
27        
28     int i(100);  // 初始化的第二种写法,同 int i = 100;; 
29     
30     printf("i = %d\n", i);
31     
32     return 0;
33 }

(一)实验结果说明:

       1,初始化和赋值看上去相同之处在于当初始化用赋值符号表达的时候;

       2,不同之处在于初始化要调用构造函数,而赋值不会;

   

五、构造函数的调用:

    1,一般情况下,构造函数在对象定义时被自动调用;

    2,一些特殊情况下,需要手工调用构造函数:

       1,如何创建对象数组;

   

六、构造函数的手工调用(第二种初始化对象方式)编程实验:

1 #include 2 
3 class Test
4 {
5 private:
6     int m_value;
7 public:
8     Test() 
9     { 
10         printf("Test()\n");
11         
12         m_value = 0;
13     }
14     Test(int v) 
15     { 
16         printf("Test(int v), v = %d\n", v);
17         
18         m_value = v;
19     }
20     int getValue()
21     {
22         return m_value;
23     }
24 };
25 
26 int main()
27 {
28     Test ta[3];  // 按照 C 语言的方法定义 3 个 Test 对象的数组 ta;结果调用了 3 个 Test() 函数;
29     
30     for(int i=0; i<3; i++)  // 循环结果打印出 3 个 0,这不一定是我们想要的;编译器默认的调用了 Test();
31     {
32         printf("ta[%d].getValue() = %d\n", i , ta[i].getValue());
33     }
34     
35     Test ta[3] = {Test(), Test(1), Test(2)};  // 手动调用构造函数;
36     
37     for(int i=0; i<3; i++)  // 循环结果为 0 1 2;分别调用了相应的构造函数;
38     {
39         printf("ta[%d].getValue() = %d\n", i , ta[i].getValue());
40     }
41     
42     Test t = Test(100);  // 初始化第二种方式,手工调用构造函数;
43     
44     printf("t.getValue() = %d\n", t.getValue());
45     
46     return 0;
47 }

七、小实例:

    (一)需求:开发一个数组类解决原生数组的安全性问题:

       1,提供函数获取数组长度;

           1C++ 要兼容 C 语言中的数组,但是 C 语言中的数组没有长度信息,用着用着就越界了;

       2,提供函数获取数组元素;

       3,提供函数设置数组元素;      

八、数组类的实现编程实验:

(一)IntArray.h 文件: 

1 #ifndef _INTARRAY_H_
2 #define _INTARRAY_H_
3 
4 class IntArray
5 {
6 private:
7     int m_length;
8     int* m_pointer;
9 public:
10     IntArray(int len);
11     int length();
12     bool get(int index, int& value);  // 用 bool 类型作为返回值是为了安全性,安全性的体现见数组类的实现;
13     bool set(int index ,int value);
14     void free();  // 用来释放 m_pointer 指向的堆空间
15 };
16 
17 #endif

(二)IntArray.cpp 文件: 

1 #include "IntArray.h"
2 
3 IntArray::IntArray(int len)  // 不加作用域分辨符时,是全局函数(此时仅名字前缀相同而已),所以要加作用域分辨符指明是数组类中的函数;
4 {
5     m_pointer = new int[len];  // new int(len) 指的是设置初始值;
6     
7     for(int i=0; i<len; i++)
8     {
9         m_pointer[i] = 0;
10     }
11     
12     m_length = len;
13 }
14 
15 int IntArray::length()
16 {
17     return m_length;
18 }
19 
20 bool IntArray::get(int index, int& value)
21 {
22     bool ret = (0 <= index) && (index < length());  // 进行安全性检查,是安全性的体现;
23     
24     if( ret )
25     {
26         value = m_pointer[index];  // 通过引用返回一个值;
27     }
28     
29     return ret;  // 越界则返回 false;
30 }
31 
32 bool IntArray::set(int index, int value)
33 {
34     bool ret = (0 <= index) && (index < length());
35     
36     if( ret )
37     {
38         m_pointer[index] = value;
39     }
40     
41     return ret;
42 }
43 
44 void IntArray::free()
45 {
46     delete[]m_pointer;
47 }

(三)IntArray 的使用:

1 #include 2 #include "IntArray.h"
3 
4 int main()
5 {
6     IntArray a(5);    
7     
8     for(int i=0; i<a.length(); i++)
9     {
10         a.set(i, i + 1);
11     }
12     
13     for(int i=0; i<a.length(); i++)
14     {
15         int value = 0;
16         
17         if( a.get(i, value) )
18         {
19             printf("a[%d] = %d\n", i, value);
20         }
21     }
22     
23     a.free();
24     
25     return 0;
26 }

(四)这里展示了面向对象的强大,我们可以通过类来封装一些之前学习到的概念,并且可以将这些概念上的缺陷通过封装来弥补开来;

   

九、小结:

(二)构造函数可以根据需要定义参数;

(三)构造函数之间可以存在重载关系;

(四)构造函数遵循 C++ 中重载函数的规则;

(五)对象定义时会触发构造函数的调用;

       1,构造函数调用方式分为自动调用和手工调用两种;

       2,自动调用的形式又分为参数式和赋值式;

       3,即初始化时,分为两种调用方式三种书写形式;

(六)在一些情况下可以手动调用构造函数;


本文由职坐标整理发布,学习更多的相关知识,请关注职坐标IT知识库!

本文由 @从安 发布于职坐标。未经许可,禁止转载。
喜欢 | 0 不喜欢 | 0
看完这篇文章有何感觉?已经有0人表态,0%的人喜欢 快给朋友分享吧~
评论(0)
后参与评论

您输入的评论内容中包含违禁敏感词

我知道了

助您圆梦职场 匹配合适岗位
验证码手机号,获得海同独家IT培训资料
选择就业方向:
人工智能物联网
大数据开发/分析
人工智能Python
Java全栈开发
WEB前端+H5

请输入正确的手机号码

请输入正确的验证码

获取验证码

您今天的短信下发次数太多了,明天再试试吧!

提交

我们会在第一时间安排职业规划师联系您!

您也可以联系我们的职业规划师咨询:

小职老师的微信号:z_zhizuobiao
小职老师的微信号:z_zhizuobiao

版权所有 职坐标-一站式IT培训就业服务领导者 沪ICP备13042190号-4
上海海同信息科技有限公司 Copyright ©2015 www.zhizuobiao.com,All Rights Reserved.
 沪公网安备 31011502005948号    

©2015 www.zhizuobiao.com All Rights Reserved

208小时内训课程