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

2,带有参数的构造函数:

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

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

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

4,代码示例:

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

3,对象定义和对象声明的区别:

1,对象定义:申请对象的空间并调用构造函数;

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

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

2,对象声明:告诉编译器存在这样一个对象;

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

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

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

3,代码示例:

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

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

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

  1. #include <stdio.h>
  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(); // 初始胡第一种方式的参数式自动调用,调用 Test(int v);这里也是定义对象,看上去非常像函数调用,但是这里是告诉编译器要调用带有参数的函数,由重载规则确定调用的是那个构造函数;
  21. Test t2 = ; // 初始化第一种方式的赋值式自动调用,调用 Test(int v);C 语言中初始化的方法,定义一个变量后,立即指明一个值,通过赋值符号指明;这在面向对象中其实也是对象的定义,并且指明想用右值初始化左值;
  22.  
  23. t = t2; // 这是赋值操作,这里运行后不会调用构造函数,没有打印语句;初始化会调用构造函数,赋值则看后续课程;
  24.  
  25. int i = ; // 用 1 对 i 进行初始化;
  26. i = ; // 用 1 对 i 进行赋值;赋值和初始化是不同的;在面向对象当中,不同在于初始化是要调用构造函数的;
  27.  
  28. int i(); // 初始化的第二种写法,同 int i = 100;;
  29.  
  30. printf("i = %d\n", i);
  31.  
  32. return ;
  33. }

1,实验结果说明:

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

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

5,构造函数的调用:

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

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

1,如何创建对象数组;

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

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

7,小实例:

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

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

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

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

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

8,数组类的实现编程实验:

1,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

2,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=; i<len; i++)
  8. {
  9. m_pointer[i] = ;
  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 = ( <= 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 = ( <= 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. }

3,IntArray 的使用:

  1. #include <stdio.h>
  2. #include "IntArray.h"
  3.  
  4. int main()
  5. {
  6. IntArray a();
  7.  
  8. for(int i=; i<a.length(); i++)
  9. {
  10. a.set(i, i + );
  11. }
  12.  
  13. for(int i=; i<a.length(); i++)
  14. {
  15. int value = ;
  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 ;
  26. }

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

9,小结:

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

2,构造函数之间可以存在重载关系;

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

4,对象定义时会触发构造函数的调用;

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

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

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

5,在一些情况下可以手动调用构造函数;

C++中构造函数的手动和自动调用方式的更多相关文章

  1. Hybrid App开发模式中, IOS/Android 和 JavaScript相互调用方式

    IOS:Objective-C 和 JavaScript 的相互调用 iOS7以前,iOS SDK 并没有原生提供 js 调用 native 代码的 API.但是 UIWebView 的一个 dele ...

  2. Python中包(package)的调用方式

     一.什么是Python Package 如何区分你看到的目录是一个Python Package包呢?其实很简单,你只要看这个名录下是否有“__init__.py”这个文件就好了,如果有那么就是Pyt ...

  3. javascript中时间的手动创建date的方式

    new Date("month dd,yyyy hh:mm:ss"); new Date("month dd,yyyy"); new Date(yyyy,mth ...

  4. C++中构造函数详解及显式调用构造函数

    C++构造函数详解及显式调用构造函数                                         c++类的构造函数详解                        一. 构造函 ...

  5. C++中构造函数作用

    一. 构造函数是干什么的 class Counter { public: // 类Counter的构造函数 // 特点:以类名作为函数名,无返回类型 Counter() { m_value = ; } ...

  6. Spring Cloud项目中通过Feign进行内部服务调用发生401\407错误无返回信息的问题

    问题描述 最近在使用Spring Cloud改造现有服务的工作中,在内部服务的调用方式上选择了Feign组件,由于服务与服务之间有权限控制,发现通过Feign来进行调用时如果发生了401.407错误时 ...

  7. C++C++中构造函数与析构函数的调用顺序

    http://blog.csdn.net/xw13106209/article/details/6899370 1.参考文献 参考1: C++继承中构造函数.析构函数调用顺序及虚函数的动态绑定 参考2 ...

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

    一般而言,析构函数调用的顺序和构造函数调用顺序相反,但是,对象的存储类别可以改变调用析构函数的顺序.举例说明: CreateAndDestroy类的定义 CreateAndDestroy类的成员函数的 ...

  9. C++学习笔记(7)----类的数组中构造函数和析构函数的调用顺序

    C++类的数组中构造函数和析构函数的调用顺序(2) 对于如下的代码: #include<iostream> using namespace std; class CBase { priva ...

随机推荐

  1. Python---项目需求分析

    一.软件工程 .软件工程:工程化方法解决软件问题 操作步骤 1.需求分析 前台:给基础用户使用的页面 后台:给操作者/admin等使用的页面系统 不是服务器前后台概念 2.小米前台 商品展示 商品详情 ...

  2. 关于antd表单的自行校验

    rules里面加上validator验证,value就是输入的值 上面为正则表达式的检验

  3. 【leetcode】Max Area of Island

    国庆中秋长假过完,又要开始上班啦.先刷个题目找找工作状态. Given a non-empty 2D array grid of 0's and 1's, an island is a group o ...

  4. Buffer转成字符串

    如果data为buffer格式,则: data.toString()

  5. 全方面了解和学习PHP框架 PHP培训教程

    PHP成为最流行的脚本语言有许多原因:灵活性,易用性等等.对于项目开发来说,我们通常需要一个PHP框架来代替程序员完成那些重复的部分.本文,兄弟连将对PHP框架进行全面解析. PHP框架是什么? PH ...

  6. 实战build-react(二)-------引入Ant Design(增加)

    https://blog.csdn.net/zhan_lijian/article/details/85271906(copy) 1.肯定参考facebook关于react官网咯 快速搭建 creat ...

  7. socket编程相关阐述

    一.socket初识 ①服务端 import socket server = socket.socket() server.bind(('127.0.0.1', 8080)) server.liste ...

  8. 微信小程序登录 code 40029 天坑

    微信登录时 code 大坑(服务端返回如下代码) {"errcode":40029,"errmsg":"invalid code, hints: [ ...

  9. (53)LINUX应用编程和网络编程之八Linux网络基础

    3.8.1.网络通信概述 3.8.1.1.从进程间通信说起:网络域套接字socket,网络通信其实就是位于网络中不同主机上面的2个进程之间的通信. 3.8.1.2.网络通信的层次 (1)硬件部分:网卡 ...

  10. DVWA--upload

    文件上传漏洞 0x01了解文件上传漏洞的用处是用来干什么的 什么是文件上传漏洞? 文件上传漏洞是指由于程序员在对用户文件上传部分的控制不足或者处理缺陷,而导致的用户可以越过其本身权限向服务器上上传可执 ...