在面向对象编程中,创建对象时系统会自动调用构造函数来初始化对象,构造函数是一种特殊的类成员函数,它有如下特点:

1. 构造函数的名子必须和类名相同,不能任意命名;
2. 构造函数没有返回值;
3. 构造函数可以被重载,但是每次对象创建时只会调用其中的一个;

我们可以将构造总结为以下几类,不同入参决定调用不同的构造函数,它们分别是普通构造函数 、默认构造函数 、拷贝构造函数 、转换构造函数;下面代码给出了复数类CComplex的多种构造函数以及相关辅助函数;

1. 普通构造函数

普通构造函数是最为常见的构造函数,它没有特殊的特点,其函数形参参数可有多个,其函数原型和测试代码如下:

//普通构造函数原型
CComplex(int nReal, int nImag);//测试代码
//需要指定参数
CComplex num1(1,1);
num1.PrintComplex();

运行结果:

2. 默认构造函数

相对于普通构造函数而言,默认构造函数是指用户可以指定实参值,也可以不指定实参值,不指定实参值,系统就使用默认的值,而且默认构造函数只可以有一个,否则有歧义;默认构造函数原型和测试代码如下:

//默认构造函原型声明
CComplex();                 //默认构造函数形式1,这里选择形式1
CComplex(int i=10,int j=10);//默认构造函数形式2//调用默认构造函数,用户可以不需要指定形参值
CComplex sum;
sum.PrintComplex();

运行结果:

3. 拷贝构造函数

拷贝构造函数,也叫做复制构造函数,主要应用于使用一个已存在的对象去初始化一个新对象,使新对象的属性和该对象保持一致。

若用户未定义拷贝构造函数,编译器就自动提供一个默认的复制构造函数,其作用仅是简单地复制类中的每个数据成员;为了安全起见,类设计者需要提供拷贝构造函数;

拷贝构造函数一般形式:

类名(const 类名& 对象名)

形如:CComplex(const CComplex& srcObj)

在以下三种情况下,拷贝构造函数将被调用;

1. 建立新对象

使用一个已存在对象num,初始化即将要被创建的新对象,可以有以下两种形式:

CComplex num1(num); //形式1
CComplex num2=num;  //形式2

运行结果:

2. 函数形参为类对象

在函数调用时需要将实参对象完整地传递给形参,系统将默认调用拷贝构造函数,建立一个实参的拷贝,这样形参对象和实参对象将具有相同的属性值;

需要注意的是,仅形参是按值传递时才会进行对象拷贝,若是传递引用,不会进行对象拷贝,

形如:

//按值传递,复制对象
static void TransByValue(CComplex obj)
//传递引用,不复制对象
static void TransByRefence(const CComplex& obj)

测试代码如下:

CComplex num(8,8);
cout << "test case result:\n" << endl;cout << "test case by refence:\n" << endl;
CComplex::TransByValue(num);cout << "test case by refence:\n" << endl;
CComplex::TransByRefence(num);

运行结果:

3. 函数返回值是类对象

当一个函数返回值是一个类对象时,在该函数返回调用处时,系统会将函数中的对象复制一份到别的地方,即使返回值没有被使用;

形如:

static CComplex GetObj()
{CComplex ret(10,10);  return ret;
}

测试代码:

//直接拷贝函数中的对象来初始化新对象num
CComplex num =  CComplex::GetObj();//函数返回值进行对象拷贝
CComplex::GetObj();

运行结果:

4. 转换构造函数

转换构造函数的作用是将一个其他类型的数据转换为一个类的对象。转换构造函数也是一种构造函数,它遵循构造函数的一般原则,我们通常把仅有一个参数的构造函数用作类型转换,所把它称为转换构造函数。

转换构造函数中的类型数据可以是普通类型,也可以是类类型,其一般形式如下:

类名(指定类型的数据)

形如:

//转换构造函数
CComplex(int nReal)

测试代码:

//定义对象
CComplex num1(1,1);cout << "test case result:\n" << endl;
//num1+2 =》
//step1:将整型数2转换为CComplex临时对象 调用转换构造函数
//step2:进行operator+运算符重载
//step3:运算符重载返回类对象
CComplex::TransByRefence(num1 + 2);

运行结果:

5. 对象拷贝和对象赋值的区别

对象的赋值是对一个已经存在的对象进行重新赋值,因此必须先定义被赋值的对象,才能进行赋值;

而对象的拷贝是在从无到有建立一个新对象,并使这个新对象和已有对象完全相同;

例如:

CComlex num1(1,1);
CCompex num2(2,2);
//对象赋值 使对象num2的值和对象num1一致,调用进行operator=运算符重载
num2 = num1;//对象拷贝,利用对象num2创建新对象num3;
CCompex num3 = num2;

6. CCompex 类实现代码

class CComplex
{
public://普通构造函数CComplex(int nReal, int nImag):m_nReal(nReal),m_nImag(nImag){cout << "common constructor function" << endl;}//默认构造函数 默认构造函仅有一个CComplex():m_nReal(10),m_nImag(10){cout << "default constructor function" << endl;}//拷贝构造函数或者复制构造函数CComplex(const CComplex& srcObj):m_nReal(srcObj.m_nReal),m_nImag(srcObj.m_nImag){cout << "copy constructor function" << endl;}//转换构造函数,也可认为是普通构造函数,需要看上下文CComplex(int nReal):m_nReal(nReal),m_nImag(0){cout << "convert constructor function" << endl;}//赋值操作运算符CComplex& operator=(const CComplex& srcObj){cout << "operate= function" << endl;//防止自我赋值,eg:a = a;if (this == &srcObj){return *this;}this->m_nReal = srcObj.m_nReal;this->m_nImag = srcObj.m_nImag;return *this;}//析构函数~CComplex(){}public://+操作运算符  辅助函数,用于说明转换构造函数friend CComplex operator+(const CComplex& srcObj1, const CComplex& srcObj2){cout << "operate+ function" << endl;int nReal = srcObj1.m_nReal+srcObj2.m_nReal;int nImag = srcObj1.m_nImag+srcObj2.m_nImag;//无名构造函数return CComplex(nReal, nImag);}void PrintComplex() const{cout << "real: " << m_nReal << " " << "imag: " << m_nImag << "\n" <<endl;}//按值传递,注意不是对象引用static void TransByValue(CComplex obj){obj.PrintComplex();}static void TransByRefence(const CComplex& obj){obj.PrintComplex();}static CComplex GetObj(){CComplex ret(10,10);return ret;}private:int m_nReal;int m_nImag;
};

转载于:https://www.cnblogs.com/jinxiang1224/p/8468239.html

c++构造函数分类说明相关推荐

  1. C++ 构造函数分类以及调用

    #define _CRT_SECURE_NO_WARNINGS #include<iostream> using namespace std;//1.分类 //按照参数进行分类 有参构造函 ...

  2. C++构造函数的分类及调用

    C++构造函数的分类及调用 构造函数的分类及调用 两种分类方式: 三种调用方式 示例 构造函数的分类及调用 两种分类方式: 按参数分为: 有参构造和无参构造 按类型分为: 普通构造和拷贝构造 三种调用 ...

  3. 【黑马程序员 C++教程从0到1入门编程】【笔记4】C++核心编程(类和对象——封装、权限、对象的初始化和清理、构造函数、析构函数、深拷贝、浅拷贝、初始化列表、友元friend、运算符重载)

    黑马程序员C++教程 文章目录 4 类和对象(类属性[成员属性],类函数[成员函数]) 4.1 封装 4.1.1 封装的意义(三种权限:public公共.protected保护.private私有)( ...

  4. 5、this调用语句必须是构造函数中的第一个可执行语句_Java 构造函数

    1.构造函数是用来干什么的 构造函数是用来初始化对象的成员属性的. 举个例子: public class MyClass {private String name;private int id;pub ...

  5. C++基础05-类构造函数与析构函数

    总结: 1.类对象的作用域为两个{}之间.在遇到}后开始执行析构函数 2.当没有任何显式的构造函数(无参,有参,拷贝构造)时,默认构造函数才会发挥作用 一旦提供显式的构造函数,默认构造函数不复存在,默 ...

  6. 【C++碎碎念】面向对象(封装与访问控制、构造函数与析构函数、拷贝函数)

    目录 一.封装与访问控制 二.构造函数与析构函数 三. 拷贝构造函数 一.封装与访问控制 1.封装的优势: 1)隐藏实现细节,提供公共的访问方式: 2)提高了代码的复用性: 3)提高了安全性. 2.分 ...

  7. Dart(7)-构造函数

    一.构造函数分类 (0) ClassName() //默认构造函数 (1) ClassName(...) //普通构造函数 (2) Classname.identifier(...) //命名构造函数 ...

  8. C++之构造函数和析构函数

    构造函数和析构函数,是C++每个类都会拥有的函数,具体作用有什么呢,一起来康康吧. 一.概念及其使用: 1.构造函数:是创建对象时,程序自动调用的,用来初始化对象的函数,其格式为: 类名 (参数列表) ...

  9. C#面向对象(一):明确几个简单的概念作为开胃菜

    绝对干货,总结了下C#面向对象的干货内容以及我几年来的使用心得,分享出来 先明确几个简单概念作为开胃菜: 1.命名空间 namespace BackStageManagement.Services 关 ...

  10. Swift3.0语法1

    (一)简介 (1)优于OC,快速,安全 (2)取消了预编译指令包括宏定义(OC用的太多了) (3)取消了OC指针和不安全访问的使用(看不到星星了) (4)全部点语法 (5)3.0中对Foundatio ...

最新文章

  1. python的.arsort()函数的用法
  2. 防摇控制matlab,一种起重机防摇控制方法与流程
  3. Spring Boot 扩展点应用之工厂加载机制
  4. 混合云存储:大数据应用的上云之道
  5. HDU1276 士兵队列训练问题【模拟+array+vector+list】
  6. 【论文笔记】Spatial Pyramid Pooling in Deep Convolutional Networks for Visual Recognition
  7. xmind 使用备忘
  8. MyBatis源码阅读(四) --- SqlSession的创建过程
  9. wifi分析仪怎么看哪个信道好_专业的WiFi检测工具有哪些?如何解决wifi信号不好?...
  10. html 日期选择器 ie8,兼容IE8的简单jQuery日期选择器插件
  11. php 汉字转拼音类,汉字与拼音转换PHP类
  12. Android 9 静默安装apk
  13. AutoCAD中添加块和块参照(转载)
  14. Python 3程序开发指南 (第二版) 中文PDF下载 Programming in Python 3, 2rd Ed - Python - 大家论坛 -...
  15. setPositiveButton和setNegativeButton和setNeutralButton
  16. 1-2、戴尔DELL服务器R730XD配置bios,raid,R720XD安装系统,DELL510配置管理口
  17. java程序笑脸怎么打_我编写的JAVA程序为什么在编译执行后会先打出一个笑脸呢?...
  18. 安全审计——等级保护日志审计要求的一种解决方案
  19. 2020最新苹果企业级开发者账号续费流程
  20. Word中所有公式转为特定文本

热门文章

  1. 636. 132 模式
  2. ruby DBI安装使用指南
  3. 《CLR via C#》读书笔记(5)基元类型、引用类型和值类型
  4. 显卡能力在cod7上的排名
  5. [Java] ActionEvent 事件处理
  6. Cisco 静态nat配置
  7. vivoz3android版本多少,谁更值得买—荣耀V10 OR vivo Z3
  8. k means sse python_python实现kMeans算法
  9. c语言中变量的转换,C语言中,指针变量之间的类型转换
  10. 图片在mysql中的储存_如何在MySQL中直接储存图片