【C++面向对象】2.构造函数、析构函数

news2024/9/24 15:22:28

文章目录

  • 【 1. 构造函数 】
    • 1.1 带参构造函数--传入数据
    • 1.2 无参构造函数--不传入数据
    • 1.3 实例
    • 1.4 拷贝构造函数
  • 【 2. 析构函数 】

【 1. 构造函数 】

  • 类的构造函数是类的一种特殊的成员函数,它会 在每次创建类的新对象时执行
  • 构造函数的名称与类的名称是完全相同的,并且 不会返回任何类型,也不会返回 void。构造函数可 用于为某些成员变量设置初始值

1.1 带参构造函数–传入数据

  • 法1
class Complex
{
	private: 
		double x;
		double y;
	public:
		Complex(); //无参构造函数
		Complex(double, double); //带参构造函数
		void Complex_Printf(void); //输出函数
};

//带参构造函数--形式1
Complex::Complex(double a, double b) 
{
	x = a;
	y = b;
}
  • 法2
class Complex
{
	private: 
		double x;
		double y;
	public:
		Complex(); //无参构造函数
		Complex(double, double); //带参构造函数
		void Complex_Printf(void); //输出函数
};
//带参构造函数--形式2
Complex::Complex(double a,double b) :x(a), y(b) { };

1.2 无参构造函数–不传入数据

  • 法1
class Complex
{
	private: 
		double x;
		double y;
	public:
		Complex(); //无参构造函数
		Complex(double, double); //带参构造函数
		void Complex_Printf(void); //输出函数
};
//无参构造函数:默认值x=2,y=1
Complex::Complex()
{
	x=2;
	y=1;
};
  • 法2
class Complex
{
	private: 
		double x;
		double y;
	public:
		Complex(); //无参构造函数
		Complex(double, double); //带参构造函数
		void Complex_Printf(void); //输出函数
};
//无参构造函数:默认值x=2,y=1
Complex::Complex() :x(2), y(1) { };

1.3 实例

// 【Complex.h】
#pragma once

class Complex
{
	private: 
		double x;
		double y;
	public:
		Complex(); //无参构造函数
		Complex(double, double); //带参构造函数
		void Complex_Printf(void); //输出函数
};
// 【 Complex.cpp 】
#include "Complex.h"
#include <iostream>
using namespace std;

//无参构造函数:默认值x=2,y=1
Complex::Complex() :x(2), y(1) {};

//带参构造函数:赋初值
Complex::Complex(double a, double b) 
{
	x = a;
	y = b;
}

//输出函数,根据实部x和虚部y,输出对应的复数
void  Complex::  Complex_Printf(void)
{
	if      (!x && !y)        cout << '0' << endl;			     //{0}  {0}   :0
	else if (x  && !y)        cout << x << endl;                 //{≠0}{0}   :x
	else if (!x && y == -1)   cout << '-i' << endl;              //{0}  {-1}  :-i
	else if (!x && y == 1)    cout << 'i' << endl;               //{0}  {1}	  :i
	else if (!x)              cout<<y<<'i'<<endl;				 //{0}  {else}:yi
	else if (x && y == 1)     cout << x << "+i" << endl;         //{≠0}{1}   :x+i
	else if (x && y == -1)    cout << x << "-i" << endl;         //{≠0}{-1}  :x-i
	else if (y > 0)           cout << x << '+' << y << 'i'<<endl;//{≠0}{>0}  :x+yi ,y>0
	else                      cout << x <<y << 'i' << endl;		 //{≠0}{<0}  :x-yi ,y<0
}
// 【 Main.cpp 】
#include <iostream>
#include "Complex.h"
using namespace std;

int main(void)
{
	Complex a;
	Complex b(0, 0);
	Complex c(0.2, 3.7);
	Complex d(0, 1);
	Complex e(2, 0);
	Complex f(3, -5);
	a.Complex_Printf();
	b.Complex_Printf();
	c.Complex_Printf();
	d.Complex_Printf();
	e.Complex_Printf();
	f.Complex_Printf();
	return 0;
}

在这里插入图片描述

1.4 拷贝构造函数

  • 拷贝构造函数是一种特殊的构造函数,它在创建对象时,是 使用同一类中之前创建的对象来初始化新创建的对象。
  • 如果在类中没有定义拷贝构造函数,编译器会自行定义一个。如果类带有指针变量,并有动态内存分配,则它必须有一个拷贝构造函数。
  • 拷贝构造函数通常用于:
    • 通过 使用另一个同类型的对象来初始化新创建的对象
    • 复制对象把它作为参数传递给函数。
    • 复制对象,并从函数返回这个对象。
  • 拷贝构造函数的常见形式:
classname (const classname &obj) 
{
   // 构造函数的主体
}
  • 实例1:
  • Line line(10); // 创建一个Line类的对象line,会调用构造函数,输出 “调用构造函数”
  • display(line); // 使用 line 作为参数传入display函数中时,系统首先会调用拷贝构造函数为 line 进行复制创建得到一个临时副本,输出 “调用拷贝构造函数并为指针 ptr 分配内存”
    系统使用该副本在 display 函数中 进行操作,输出 “line 大小 :10”,display 函数结束后该副本作为局部变量被回收,输出 “释放内存”
  • 对象 Line 在主程序结束前 也将被回收,输出 “释放内存”
#include <iostream>

using namespace std;

class Line
{
   public:
      int getLength( void );
      Line( int len );             // 简单的构造函数
      Line( const Line &obj);      // 拷贝构造函数
      ~Line();                     // 析构函数

   private:
      int *ptr;
};

// 构造函数
Line::Line(int len)
{
    cout << "调用构造函数" << endl;
    // 为指针分配内存
    ptr = new int;
    *ptr = len;
}

// 拷贝构造函数 
Line::Line(const Line &obj)
{
    cout << "调用拷贝构造函数并为指针 ptr 分配内存" << endl;
    ptr = new int;
    *ptr = *obj.ptr; // 拷贝值
}

// 析构函数 
Line::~Line(void)
{
    cout << "释放内存" << endl;
    delete ptr;
}

// 成员函数 
int Line::getLength( void )
{
    return *ptr;
}

// 外部函数 
void display(Line obj); 

// 程序的主函数
int main( )
{
   Line line(10);
   display(line);
   return 0;
}

// 一个外部函数 
void display(Line obj)
{
   cout << "line 大小 : " << obj.getLength() <<endl;
}

在这里插入图片描述

  • 实例2:
  • Line line1(10); // 创建一个Line类的对象line1,会调用构造函数,输出 “调用构造函数”
  • Line line2 = line1; // 创建一个Line类的对象line2 且 lin2 是由 lin1 复制得到,即调用了拷贝构造函数,输出 “调用拷贝构造函数并为指针 ptr 分配内存”
  • display(line1); // 使用 line1 作为参数传入display函数中时,系统首先会调用拷贝构造函数为 line1 进行复制创建得到一个临时副本,输出 “调用拷贝构造函数并为指针 ptr 分配内存”
    系统使用该副本在 display 函数中 进行操作,输出 “line 大小 :10”
    display 函数结束后该副本作为局部变量被回收,输出 “释放内存”
  • 同样地, display(line2); // 使用 line2 作为参数传入display函数中时,系统首先会调用拷贝构造函数为 line2 进行复制创建得到一个临时副本,输出 “调用拷贝构造函数并为指针 ptr 分配内存”
    系统使用该副本在 display 函数中 进行操作,输出 “line 大小 :10”
    display 函数结束后该副本作为局部变量被回收,输出 “释放内存”
  • 对象 Line1 和Line2 在主程序结束前 也将被回收,分别输出 “释放内存”
#include <iostream>

using namespace std;

class Line
{
   public:
      int getLength( void );
      Line( int len );             // 简单的构造函数
      Line( const Line &obj);      // 拷贝构造函数
      ~Line();                     // 析构函数

   private:
      int *ptr;
};

// 构造函数
Line::Line(int len)
{
    cout << "调用构造函数" << endl;
    // 为指针分配内存
    ptr = new int;
    *ptr = len;
}

// 拷贝构造函数 
Line::Line(const Line &obj)
{
    cout << "调用拷贝构造函数并为指针 ptr 分配内存" << endl;
    ptr = new int;
    *ptr = *obj.ptr; // 拷贝值
}

// 析构函数 
Line::~Line(void)
{
    cout << "释放内存" << endl;
    delete ptr;
}

// 成员函数 
int Line::getLength( void )
{
    return *ptr;
}

void display(Line obj); 


// 程序的主函数
int main( )
{
   Line line1(10);

   Line line2 = line1; // 这里也调用了拷贝构造函数

   display(line1);
   display(line2);

   return 0;
}

// 外部函数 
void display(Line obj)
{
   cout << "line 大小 : " << obj.getLength() <<endl;
}

在这里插入图片描述

【 2. 析构函数 】

  • 类的析构函数是类的一种特殊的成员函数, 类的析构函数会在每次删除所创建的对象时执行。

  • 析构函数的 名称与类的名称是完全相同的,只是在前面加了个 波浪号(~) 作为前缀,它 不会返回任何值,也 不能带有任何参数

  • 析构函数 有助于在跳出程序(比如关闭文件、释放内存等)前释放资源

  • 如果程序里没有构造函数和析构函数,编译器在编译的时候会自动生成构造函数和析构函数,只是函数内没有任何操作。

  • 实例

#include <iostream>

using namespace std;

class Line
{
   public:
      void setLength( double len );
      double getLength( void );
      Line();   // 这是构造函数声明
      ~Line();  // 这是析构函数声明

   private:
      double length;
};

// 成员函数定义,包括构造函数
Line::Line(void)
{
    cout << "Object is being created" << endl;
}
Line::~Line(void)
{
    cout << "Object is being deleted" << endl;
}

void Line::setLength( double len )
{
    length = len;
}

double Line::getLength( void )
{
    return length;
}
// 程序的主函数
int main( )
{
   Line line;

   // 设置长度
   line.setLength(6.0); 
   cout << "Length of line : " << line.getLength() <<endl;

   return 0;
}

在这里插入图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1111272.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

ARM可用的可信固件项目简介

安全之安全(security)博客目录导读 目录 一、TrustedFirmware-A (TF-A) 二、MCUboot 三、TrustedFirmware-M (TF-M) 四、TF-RMM 五、OP-TEE 六、Mbed TLS 七、Hafnium 八、Trusted Services 九、Open CI 可信固件为Armv8-A、Armv9-A和Armv8-M提供了安全软件的参考实现…

MT8195/MTK8195安卓核心板-安卓智能模块

MT8195安卓核心板是一款先进的处理器&#xff0c;采用了台积电的6纳米制程技术。它由4个Cortex-A78大核和4个Cortex-A55小核组成&#xff0c;搭配Mali-G57MC5 GPU和APU 3.0&#xff0c;算力高达4 TOPs。该核心板支持四通道LPDDR4X 2133MHz内存&#xff0c;具备出色的性能。此外…

java并发编程之基础与原理1

java多线程基础 下面说一下线程的7种状态 下面我重点来说一下阻塞状态 阻塞状态是可以分很多种的&#xff1a; 下面用另外一张图来说明这种状态 简单说一下线程的启动原理 下面说一下java中的线程 java线程的异步请求方式 上面就会先把main执行出来&#xff0c;等阻塞结束之后…

变化检测数据集制作详细版

本文记录在进行变化检测数据集制作过程中所使用的代码 首先需要准备相同地区不同时间的两幅影像&#xff0c;裁减成合适大小&#xff0c;如256*256。相同区域命名相同放在两个文件夹下。 接着使用labelme对变化区域进行标注&#xff0c;这里不再进行labelme安装及标注的赘述。…

MAC如何在根目录创建文件

在这之前先明确一下啥是根目录。 打开终端&#xff0c;输入cd /&#xff0c;然后输入 ls 查看根目录下有哪些文件 可以看到 usr、etc、opt 这些文件的地方才叫根目录&#xff0c;而不是以用户命名&#xff0c;可以看到音乐、应用程序、影片、桌面的地方哈 介绍一种叫做软连接…

C++算法:数据流的中位数

题目 中位数是有序整数列表中的中间值。如果列表的大小是偶数&#xff0c;则没有中间值&#xff0c;中位数是两个中间值的平均值。 例如 arr [2,3,4] 的中位数是 3 。 例如 arr [2,3] 的中位数是 (2 3) / 2 2.5 。 实现 MedianFinder 类: MedianFinder() 初始化 MedianFin…

数据预处理—滑动窗口采样数据

一个简单的例子&#xff1a; # data: 这是要应用滑动窗口采样的输入数据&#xff0c;通常是一个序列&#xff0c;例如列表或NumPy数组。 # window_size: 这是滑动窗口的大小&#xff0c;表示每个窗口中包含的元素数量。 # step_size: 这是滑动窗口移动的步长&#xff0c;表示每…

(※)力扣刷题-栈和队列-用队列实现栈

255.用队列实现栈 使用队列实现栈的下列操作&#xff1a; push(x) – 元素 x 入栈 pop() – 移除栈顶元素 所以后面实现的时候会留下一个元素 top() – 获取栈顶元素 empty() – 返回栈是否为空 注意: 你只能使用队列的基本操作-- 也就是 push to back, peek/pop from front, …

2023年中国粘度指数改进剂行业需求现状及前景分析[图]

润滑油添加剂指用于提高润滑油使用性能、耐久性及功效&#xff0c;从而增强机械和发动机使用性能的产品&#xff0c;分为单剂和复合剂两大类产品。单剂产品主要是清净剂、分散剂、抗氧抗腐剂、极压抗磨剂、抗氧剂、增粘剂、防锈剂、降凝剂等具有单一特性的添加剂产品&#xff1…

存储数据保护技术——HyperClone克隆与HyperMirror卷镜像技术介绍

目录 HyperClone克隆 基本概念 克隆的特点 工作原理 注意事项 HyperMirror卷镜像 HyperClone克隆 基本概念 克隆是快照技术的一种&#xff1b;在不中断主机业务的情况下&#xff0c;对源数据在某个时间点的一致性数据副本&#xff0c;数据同完成后成为完整的数据副本 …

一天吃透Java集合面试八股文

内容摘自我的学习网站&#xff1a;topjavaer.cn 常见的集合有哪些&#xff1f; Java集合类主要由两个接口Collection和Map派生出来的&#xff0c;Collection有三个子接口&#xff1a;List、Set、Queue。 Java集合框架图如下&#xff1a; List代表了有序可重复集合&#xff0c…

【C++笔记】模板进阶

【C笔记】模板进阶 一、非类型模板参数二、类模板的特化三、模板的分离编译 一、非类型模板参数 我们之前学过的模板虽然能很好地帮我们实现泛型编程&#xff0c;比如我们可以让一个栈存储int类型的数据&#xff0c;一个栈存储double类型的数据&#xff1a; template <cla…

Git 为文件添加执行权限

背景 当你是一台Linux&#xff0c;想要给文件加权限很简单&#xff0c;只需要执行以下命令 chmod x filename就可以给文件添加执行权限&#xff0c;但是如果你是Windows那就很麻烦了 解决方案 假设这里有一个名为 file.sh 的文件&#xff0c;内容如下&#xff1a; #!/bin/…

视频剪辑SDK,实现高效的移动端视频编辑

为了满足企业对视频编辑的需求&#xff0c;美摄提供了iOS/Android端视频编辑SDK技术开发服务&#xff0c;帮助企业快速高效地制作高质量视频。本文将详细介绍美摄的视频编辑SDK的优势和特点&#xff0c;以及如何为企业提供技术解决方案。 随着智能手机的普及和移动互联网的发展…

Java_Jdbc

目录 一.JDBC概述 二.JDBC API 三.ResultSet[结果集] 四.Statement 五.PreparedStatement 六. JDBC API 总结 一.JDBC概述 JDBC 为访问不同的数据库提供了同一的接口&#xff0c;为使用着屏蔽了细节问题Java程序员使用JDBC 可以连接任何提供了 JDBC驱动的数据库系统&am…

(缺省参数)(函数重载)(引用)(内敛)(C++中的nullptr)

&#xff08;缺省参数&#xff09;&&#xff08;函数重载&#xff09;&&#xff08;引用&#xff09;&&#xff08;内敛&#xff09;&&#xff08;atuo用法&#xff09;&&#xff08;C中的NULL&#xff09; 1.缺省参数1.1缺省参数的概念1.2缺省参数的分类1…

谈谈电商App的压测

背景 最近恰逢双十一&#xff0c;大大小小的电商app在双十一之前都会做一次压测&#xff0c;曾经在小公司工作的时候很想知道大公司是如何压测的&#xff0c;有什么高深的压测工具没&#xff0c;本文就来揭露一下 压测真相 在确认使用什么压测工具进行压测之前&#xff0c;我…

(※)力扣刷题-栈和队列-用栈实现队列

使用栈实现队列的下列操作&#xff1a; push(x) – 将一个元素放入队列的尾部。pop() – 从队列首部移除元素。peek() – 返回队列首部的元素。empty() – 返回队列是否为空。 说明: 你只能使用标准的栈操作 – 也就是只有 push to top, peek/pop from top, size, 和 is empt…

R6G alkyne, 6-isomer可在反应中作为底物或催化剂发挥作用

试剂 | 基础知识概述&#xff08;部分&#xff09;: 英文名&#xff1a;R6G alkyne, 6-isomer 分子式&#xff1a;C30H29N3O4 分子量&#xff1a;495.57 Ex &#xff1a;518nm Em&#xff1a;542nm 规格标准&#xff1a;10mg、25mg、50mg&#xff0c;可提供mg级以及kg级的…

系统架构师备考倒计时16天(每日知识点)

1.信息化战略与实施 2.UML图&#xff08;12个&#xff09; 3.结构化设计&#xff08;耦合&#xff09; 4.SMP与AMP的区别&#xff08;多核处理器的工作方式&#xff09; 多核处理器一般有SMP和AMP两种不同的工作方式: SMP(对称多处理技术)&#xff1a;将2颗完全一样的处理器封…