对象的初始化

对象时类的实例,类是不占用空间的,对象是占用空间的。

因为类是抽象的,不占用空间的,所以我们不能再定义类的时候对对象进行初始化操作的。

但是,我们可以定义一个函数,在类实例化一个对象的时候,对对象赋初值,这个函数就叫做构造函数

构造函数是类在定义对象的时候,自动执行的对对象中的数据进行初始化操作的函数。

构造函数的作用

构造函数不同于其他的函数,不需要用户调用它(用户也不可以调用这个函数),而是在建立对象时自动执行的。构造函数的名字必须与类名相同,以便编译系统能识别它并把它作为构造函数处理。

它不具有任何类型,不返回任何值。构造函数的功能是由用户定义的,用户根据初始化的要求设计函数体和函数参数。

===================例子1===================================

  1. #include<iostream>
  2. using namespace std;
  3. class Time{
  4. public:
  5. Time(){//定义构造函数,注意函数名必须与类名相同
  6. hour=10;
  7. minute=10;
  8. sec=10;
  9. }
  10. void set_time();
  11. void show_time();
  12. private:
  13. int hour;
  14. int minute;
  15. int sec;
  16. };
  17. void Time::set_time(){
  18. cout<<"hour :";
  19. cin>>hour;
  20. cout<<"minute :";
  21. cin>>minute;
  22. cout<<"sec :";
  23. cin>>sec;
  24. }
  25. void Time::show_time(){
  26. cout<<"Time : "<<hour<<":"<<minute<<":"<<sec<<endl;
  27. }
  28. int main(){
  29. Time t1;
  30. t1.show_time();
  31. cout<<"======================="<<endl;
  32. Time t2;
  33. t2.set_time();
  34. t2.show_time();
  35. }

当然,构造函数也可以在类外定义:

  1. #include<iostream>
  2. using namespace std;
  3. class Time{
  4. public:
  5. Time();
  6. void set_time();
  7. void show_time();
  8. private:
  9. int hour;
  10. int minute;
  11. int sec;
  12. };
  13. Time::Time(){//注意构造函数是没有返回值的
  14. hour=10;
  15. minute=10;
  16. sec=10;
  17. }
  18. void Time::set_time(){
  19. cout<<"hour :";
  20. cin>>hour;
  21. cout<<"minute :";
  22. cin>>minute;
  23. cout<<"sec :";
  24. cin>>sec;
  25. }
  26. void Time::show_time(){
  27. cout<<"Time : "<<hour<<":"<<minute<<":"<<sec<<endl;
  28. }
  29. int main(){
  30. Time t1;
  31. t1.show_time();
  32. cout<<"======================="<<endl;
  33. Time t2;
  34. t2.set_time();
  35. t2.show_time();
  36. }

构造函数的声明和定义与其他的函数是有区别的,它没有返回值。

构造函数的3个特点:

1.函数的调用是在类对象进入其作用域时自动调用的。

2.构造函数没有返回值,因此也不需要在定义构造函数时声明类型,这是它和一般函数的一个重要的不同之处。

不能写成:

否则会报错

3.构造函数不需要用户调用,也不能被用户调用。

这样写是错误的:

否则会报错

构造函数是在建立对象时由系统自动执行的,而且只能执行一次。

构造函数一般声明为public,若声明成private就会报错。

带参数的构造函数

上面介绍的构造函数虽然可以初始化对象,但是用来初始化的值都是一样的,这显然不符合实际情况。

带参数的构造函数就是用来解决这个问题的,它可以实现在调用不同对象的时候,用不同的值进行初始化。

一般格式是:

构造函数名(类型1 形参1,类型2 形参2,……)

构造函数的第三个特点是它不能采用常规的调用函数的方法给出实参(如,fun(a,b)),

实参是在定义对象时给出的,定义对象的一般格式是:

类名 对象名(实参1,实参2,……)

也就是说,它是在定义对象的时候进行传值的。

=========================例子2==============================

有两个长方体,其长宽高分别是:(1)12,20,25(2)10,14,20。分别求它们的体积

  1. #include<iostream>
  2. using namespace std;
  3. class Box{
  4. public:
  5. Box(int,int,int);//声明带参数的构造函数
  6. int volume();//声明求体积的函数
  7. private:
  8. int height;
  9. int width;
  10. int length;
  11. };
  12. Box::Box(int h,int w,int l){//定义带参数的构造函数
  13. height=h;
  14. width=w;
  15. length=l;
  16. }
  17. int Box::volume(){//定义求体积的函数
  18. int z;
  19. z=height*width*length;
  20. return z;
  21. }
  22. int main(){
  23. Box b1(10,10,10);
  24. cout<<"Volume of b1 : "<<b1.volume()<<endl;
  25. Box b2(10,20,30);
  26. cout<<"Volume of b2 : "<<b2.volume()<<endl;
  27. return 0;
  28. }

可以知道:

(1)带参数的构造函数中的形参,其对应的实参在定义对象时给定。

(2)用这种方法可以方便地实现对不同的对象进行不同的初始化。

用参数初始化表对数据成员初始化

这种烦好伐不在函数体内对数据成员初始化,而是在函数首部实现。

  1. Box::Box(int h,int w,int l):height(h),width(w),length(l){}

即,在原来函数首部的末尾加一个冒号,然后列出参数的初始化表。

上面的初始化表表示:用形参h的值初始化数据成员height;用形参w的值初始化数据成员width;用形参l的值初始化数据成员。

这种写法更加方便,简单,尤其当需要初始化的数据成员较多的时候,更显其优越性~

然而,很多时候,我们不仅需要不同的对象的初始化值不同,有些时候我们还想要使用默认的一些初始化值。

有两种方法可以实现:

构造函数的重载

在一个类中定义多个构造函数,以便对类对象提供不同的初始化方法,供用户选用。这些构造函数具有相同的名字,而参数的个数或参数的类型不同。

  1. #include<iostream>
  2. using namespace std;
  3. class Box{
  4. public:
  5. Box(int,int,int);//含参数的构造函数
  6. Box();//不含参数的构造函数
  7. int volume();
  8. private:
  9. int height;
  10. int width;
  11. int length;
  12. };
  13. Box::Box(){
  14. height=0;
  15. width=0;
  16. length=0;
  17. }
  18. Box::Box(int h,int w,int l):height(h),width(w),length(l){}
  19. int Box::volume(){
  20. int z;
  21. z=height*width*length;
  22. return z;
  23. }
  24. int main(){
  25. Box b1;//实例化对象的时候没有进行传值
  26. cout<<"Volume of b1 : "<<b1.volume()<<endl;
  27. Box b2(10,20,30);//实例化对象的时候进行传值
  28. cout<<"Volume of b2 : "<<b2.volume()<<endl;
  29. return 0;
  30. }

编译系统是根据函数调用(在类实例化对象的时候自动进行)的时候,是否传值,以及传值的个数和类型进行判断的。

(1)调用构造函数的时候,不必给出实参的构造函数,成为默认构造函数(或称为缺省构造函数)。

显然,无参构造函数属于默认构造函数,而且一个类只能定义一个默认构造函数。

(2)尽管在一个类中可以包含多个构造函数,但是对于每一个对象来说,建立对象时只执行其中一个构造函数,并非每个构造函数都被执行。

使用默认参数的构造函数

  1. #include<iostream>
  2. using namespace std;
  3. class Box{
  4. public:
  5. Box(int h=1,int w=1,int l=1);//含默认参数的构造函数
  6. int volume();
  7. private:
  8. int height;
  9. int width;
  10. int length;
  11. };
  12. Box::Box(int h,int w,int l):height(h),width(w),length(l){}
  13. int Box::volume(){
  14. int z;
  15. z=height*width*length;
  16. return z;
  17. }
  18. int main(){
  19. Box b1;
  20. cout<<"Volume of b1 : "<<b1.volume()<<endl;
  21. Box b2(10,20,30);
  22. cout<<"Volume of b2 : "<<b2.volume()<<endl;
  23. return 0;
  24. }

(1)默认参数可以在声明构造函数的时候指定,也可以在定义构造函数的时候指定

  1. Box::Box(int h=1,int w=1,int l=1):height(h),width(w),length(l){}

(2)在声明构造函数的时候,形参名可以省略,即简写成:

  1. Box(int =1,int =1,int =1);//含参数的构造函数

(3)如果构造函数的全部参数都指定了默认值,则在定义对象时可以给定一个或者几个实参,也可以不给出实参。

  1. Box b2(10,20);

对应的结果是200

前面说了,不需要实参也可以调用的构造函数成为缺省构造函数,并且,一个类只能有一个缺省构造函数,也就是说可以不使用参数而调用的构造函数,一个类只能有一个。

其道理是显然的,因为缺省构造函数不唯一的话,编译系统就不知道在实例化对象的时候,没有传递实参的情况下,应该调用哪一个函数了。

C++中的构造函数小结的更多相关文章

  1. 解析C#类中的构造函数

    <解析C#类中的构造函数> 一.  C#中的构造函数概述: C#中类包含数据成员和函数成员.函数成员提供了操作类中数据的某些功能,包括方法.属性.构造器和终结器.运算符和索引器. 构造函数 ...

  2. Java中的构造函数和重载

    一.Java中的构造函数 构造函数是对象被创建时初始化对象的成员方法,它具有和它所在的类完全一样的名字.构造函数只能有入口参数,没有返回类型,因为一个类的构造方法的返回类就是类本身.构造函数定义后,创 ...

  3. 在 MVC 控制器中使用 构造函数时行依赖注入 (IoC)

    在 Controller 中使用 构造函数进行依赖注入 (IoC) 1. Controller 代码: ICard card; ICardCategory cardCategory; public C ...

  4. C++中复制构造函数与重载赋值操作符总结

    前言 这篇文章将对C++中复制构造函数和重载赋值操作符进行总结,包括以下内容: 1.复制构造函数和重载赋值操作符的定义: 2.复制构造函数和重载赋值操作符的调用时机: 3.复制构造函数和重载赋值操作符 ...

  5. 20150214—winform中使用构造函数传值

    构造函数,在函数初始化时就会执行的函数方法,在创建一个类之后,系统会自动在此类中生成一个与类名相同的函数,其中只包含一句代码: InitializeComponent(); 新建一个名字相同的函数,然 ...

  6. C++中的构造函数,拷贝构造函数和赋值运算

    关于C++中的构造函数,拷贝构造函数和赋值运算,以前看过一篇<高质量C++/C编程指南>的文章中介绍的很清楚,网上能搜索到,如果想详细了解这方面的知识可以参看一下这篇文章. 常见的给对象赋 ...

  7. Java反射机制(获取Class对象的三种方式+获取Class中的构造函数进行对象的初始化+获取反射类的字段+获取反射类的一般方法)

    反射技术其实就是动态加载一个指定的类,并获取该类中的所有内容.而且将字节码文件封装成对象,并将字节码文件中的内容都封装成对象,这样便于操作这些成员,简单来说:反射技术可以对一个类进行解剖,反射大大增强 ...

  8. C++类继承中的构造函数和析构函数 调用顺序

    思想: 在C++的类继承中,构造函数不能被继承(C11中可以被继承,但仅仅是写起来方便,不是真正的继承) 建立对象时,首先调用基类的构造函数,然后在调用下一个派生类的构造函数,依次类推: 析构对象时, ...

  9. Java中有关构造函数的一道笔试题解析

    Java中有关构造函数的一道笔试题解析 1.详细题目例如以下 下列说法正确的有() A. class中的constructor不可省略 B. constructor必须与class同名,但方法不能与c ...

随机推荐

  1. Video Brightness Enhancement

    Tone Mapping原是摄影学中的一个术语,因为打印相片所能表现的亮度范围不足以表现现实世界中的亮度域,而如果简单的将真实世界的整个亮度域线性压缩到照片所能表现的亮度域内,则会在明暗两端同时丢失很 ...

  2. 321list,元组,range**数字是不可迭代的!

    一.list(列表) 列表是python中的基础数据类型之一,他是以[]括起来,每个元素以逗号隔开,而且他里面可以存放各种数据类型.列表相比于字符串,不仅可以储存不同的数据类型,而且可以储存大量数据, ...

  3. 第三篇、javascript整数和字符串

    一.整数 JavaScript中不区分整数值和浮点数值,JavaScript中所有数字均用浮点数值表示. 转换: parseInt(..)    将某值转换成数字,不成功则NaN parseFloat ...

  4. cat echo 打印菜单

    cat << END        =============================        1.apple        2.pear        3.banana   ...

  5. poj 1426 Find The Multiple 搜索进阶-暑假集训

    E - Find The Multiple Time Limit:1000MS     Memory Limit:10000KB     64bit IO Format:%I64d & %I6 ...

  6. BZOJ2034 [2009国家集训队]最大收益

    本文版权归ljh2000和博客园共有,欢迎转载,但须保留此声明,并给出原文链接,谢谢合作. 本文作者:ljh2000 作者博客:http://www.cnblogs.com/ljh2000-jump/ ...

  7. UOJ171 【WC2016】挑战NPC

    本文版权归ljh2000和博客园共有,欢迎转载,但须保留此声明,并给出原文链接,谢谢合作. 本文作者:ljh2000 作者博客:http://www.cnblogs.com/ljh2000-jump/ ...

  8. Linux课程---7、shell技巧(获取帮助命令)

    Linux课程---7.shell技巧(获取帮助命令) 一.总结 一句话总结: ls --help:简单手册 man ls:内容手册 1.tab补全? 命令+tab:加快敲命令敲文件目录的速度,多敲几 ...

  9. 文本去重之MinHash算法——就是多个hash函数对items计算特征值,然后取最小的计算相似度

    来源:http://my.oschina.net/pathenon/blog/65210 1.概述     跟SimHash一样,MinHash也是LSH的一种,可以用来快速估算两个集合的相似度.Mi ...

  10. png8 png24 png32

    解释 PNG8 : 8位的PNG最多支持256(2的8次方)种颜色,8位的PNG支持不透明.索引透明.alpha透明. PNG24 : 支持2的24次方种颜色,表现为不透明.PS导出PNG24是会根据 ...