当前位置: 首页 > news >正文

c++的几种构造函数

c++的几种构造函数

        • 构造函数
          • 拷贝构造函数
          • 转换构造函数
          • 移动构造函数
        • 析构函数

构造函数

C++中的构造函数可以分为5类:默认构造函数、普通构造函数、拷贝构造函数、转换构造函数、移动构造函数。

好像还有委托构造

默认构造和普通构造和java基本一样

详细

拷贝构造函数

拷贝构造函数用于从另一个已存在的对象创建新对象。 而不共享原始对象的数据。

class Person {
public:string name;int age;Person(const Person& other) { // 拷贝构造函数name = other.name;age = other.age;}
};int main() {Person p1("Alice", 30); // 创建 Person 对象Person p2(p1); // 拷贝构造函数创建 p2Person p3=p1;//!!!这样也会调用拷贝构造函数,这是全新的对象 和java不一样cout << p2.name << ", " << p2.age << endl; // 输出:Alice, 30return 0;
}

如果你没有显式定义拷贝构造函数,编译器会自动生成一个默认拷贝构造函数。这个默认的拷贝构造函数会逐成员地对对象进行浅拷贝

补充!!

Complex c2(c1);
Complex c2 = c1;
//这两条语句是等价的。复制构造函数的调用
Complex c1, c2;
c1=c2;
//第二条语句是初始化语句,不是赋值语句。不会调用复制构造函数,
//此时是对 c1 赋予新的值 c2,这会调用类的拷贝赋值运算符operator=()
//在 C++ 中,c1 = c2; 是深拷贝行为。c1 和 c2 是两个独立的对象。c1 = c2; 将 c2 的值拷贝到 c1,相当于复制了 c2 的内容。

还有补充!!!

class A{
public:A(){};A(A & a){cout<<"Copy constructor called"<<endl;}
};
void Func(A a){ }
int main(){A a;Func(a); //这里会调用A类的拷贝构造函数,return 0;
}

如果形参是一个对象,那么形参的值是否等于实参,取决于该对象所属的类的复制构造函数是如何实现的。如果复制构造函数随便写的,那传进去的就…

在函数被调用时,生成的形参要用复制构造函数初始化,这会带来时间上的开销。可以用将形参声明为对象的 const 引用代替

转换构造函数

一个构造函数接收一个不同于其类类型的形参,可以视为将其形参转换成类的一个对象。像这样的构造函数称为转换构造函数。在 C++ string 类中可以找到使用转换构造函数的实用示例。string 类提供一个将 C 字符串转换为 string 的转换构造函数

class string
{//仅显示转换构造函数public:string(char *);//形参时其他类型变量,且只有一个形参
};
移动构造函数

移动构造和move
建议这一篇我的笔记

下面这个例子是没有使用移动构造函数的,会有内存的浪费

// g++ 14_Copy_Date.cpp -std=c++11
#include <iostream>
#include <stdio.h>
#include <string.h>using namespace std;#define MAX_NEW_MEM		(64*1000*1000)class CDate
{
public:CDate(int year, int mon, int day);	// 构造函数声明CDate(const CDate& date);			// 拷贝构造函数声明~CDate();							// 析构函数声明CDate operator+(int day);			// 加号运算符声明void show(){cout << "Date: " << m_year << "." << m_mon << "." << m_day << ", this=" << this << endl;//cout << "Date: " << str << endl;}private:int m_year;int m_mon;int m_day;char *str;
};// 构造函数定义
CDate::CDate(int year, int mon, int day)
{m_year = year;m_mon = mon;m_day = day;str = new char[MAX_NEW_MEM];sprintf(str, "%4d.%02d.%02d", year,mon,day);cout << "Calling Constructor" << ", this=" << this <<endl;
}// 拷贝构造函数定义
CDate::CDate(const CDate& date)
{m_year = date.m_year;m_mon = date.m_mon;m_day = date.m_day;str = new char[MAX_NEW_MEM];memcpy(str, date.str, MAX_NEW_MEM);cout << "Calling Copy Constructor" << ", this=" << this << ", Copy Data" <<endl;
}// 析构函数定义
CDate::~CDate()
{cout << "Calling Destructor" << ", this=" << this <<endl;delete [] str;
}CDate CDate::operator+(int day)
{CDate temp = *this;temp.m_day += day;cout << "Calling operator+" << ", this=" << &temp << endl;return temp;
}int main()
{CDate date(2024,06,07);cout << endl;CDate date1 = std::move(date+1);// std::move 强制将 date+1 的求值结果转为右值//std::move 强制将 date+1 的求值结果转为右值,避免编译器优化;//这里其实 std::move(date+1) 是temp//temp 对象赋值给date1之后,就销毁了,如果可以直接将temp对象的资源给到date1,就可以减少一次复制。date1.show();cout << endl;return 0;
}

在这里插入图片描述

参考

移动构造:

CDate(CDate &&date) noexcept;	// 声明
CDate::CDate(CDate&& date) noexcept // 实现 加上noexcept,用于通知标准库不抛出异常。提高性能
{m_year = date.m_year;m_mon = date.m_mon;m_day = date.m_day;str = date.str;date.str = NULL;cout << "Calling Move Constructor" << ", this=" << this <<endl;
}
int main()
{CDate date(2024,06,07);CDate date1 = std::move(date+1);// std::move 强制将 date+1 的求值结果转为右值date1.show();return 0;
}

运行结果:可以看到相比于第一小节的代码,这里调用了移动构造函数,减少了一次拷贝。

std::move

class B
{
public:B() {}B(const B&) { cout << "B Copy Constructor" << endl; }
};class A {
private:B* pb;public:// 默认构造函数A() {pb = new B();cout << "A Constructor" << endl;}// 拷贝构造函数(深拷贝)A(const A& src) {pb = new B(*(src.pb));cout << "A Copy Constructor" << endl;}// 移动构造函数A(A&& src) noexcept {pb = src.pb;src.pb = nullptr; // 防止 src 析构时释放原来的堆内存cout << "A Move Constructor" << endl;}// 析构函数~A() {delete pb;cout << "A Destructor" << endl;}
};static A getA()
{A a;cout << "================================================" << endl;return a;
}int main()
{A a = getA();//A a = getA();调用的是A的移动构造,cout << "================================================" << endl;A a1(a);//A a1(a); 调用的是A的拷贝构造。A的拷贝构造需要对成员变量B进行深拷贝cout << "================================================" << endl;A a2(std::move(a));//A a2(std::move(a));将a转换为右值,因此a2调用的是移动构造而不是拷贝构造。system("pause");return 0;
}
析构函数

它会在每次删除所创建的对象时执行。

析构函数的名称与类的名称是完全相同的,只是在前面加了个波浪号(~)作为前缀

相关文章:

c++的几种构造函数

c的几种构造函数 构造函数拷贝构造函数转换构造函数移动构造函数 析构函数 构造函数 C中的构造函数可以分为5类&#xff1a;默认构造函数、普通构造函数、拷贝构造函数、转换构造函数、移动构造函数。 好像还有委托构造 默认构造和普通构造和java基本一样 详细 拷贝构造函…...

FRP 实现内网穿透

如何通过 FRP 实现内网穿透&#xff1a;群晖 NAS 的 Gitea 和 GitLab 访问配置指南 在自建服务的过程中&#xff0c;经常会遇到内网访问受限的问题。本文将介绍如何利用 FRP&#xff08;Fast Reverse Proxy&#xff09;来实现内网穿透&#xff0c;以便在外网访问群晖 NAS 上的…...

数据结构笔记(其八)--一般树的存储及其遍历

1.知识总览 一般的树会有多个孩子&#xff0c;所以存储结构也会与二叉树略有不同。 一般树的遍历。 2.双亲表示法 双亲表示法&#xff0c;也是父亲表示法&#xff0c;即每个节点中都存储了其父节点的地址信息。 特性&#xff1a;可以轻易地找到父节点&#xff0c;但寻找孩子节…...

在spring boot工程中使用Filter时,@WebFilter 注解不生效的问题分析和解决方案

1. 问题描述 首先编写一个Filter类并通过Component放入spring容器中&#xff0c;通过实现jakarta.servlet中提供的Filter接口完成过滤器的创建&#xff0c;代码如下。 import jakarta.servlet.*; import jakarta.servlet.annotation.WebFilter; import org.springframework.st…...

浅谈“通感一体”

文章目录 5G_Advanced的关键技术通感一体的介绍通感一体应用通感一体面临的挑战 5G_Advanced的关键技术 2024年6月18日16点30分&#xff0c;在上海举行的3GPP RAN第104次会议上&#xff0c;R18标准正式冻结&#xff0c;标志着5G技术的又一重要里程碑。值得注意的是&#xff0c…...

【Linux】监控系统Zabbix的安装与配置

文章目录 一、前期准备1、安装LAMP2、配置SELinux与防火墙3、测试Apache4、配置数据库5、创建zabbix数据库及应用 二、server端安装配置1、软件包安装2、配置数据库3、zabbix访问测试4、配置web界面 三、Agent端安装配置1、安装zabbix-agent2、配置3、启动zabbix-agent4、配置防…...

Springboot定时任务

Component EnableScheduling public class SpringBootTestJob {Scheduled(cron "0/5 * * * * ?")public void testScheduled(){System.out.println("SpringBootTestJob test");} }这段代码使用了 Spring Boot 自带的定时任务机制。解释如下&#xff1a; …...

node.js知识点总结

1、Node.js Node. js是一个基于 Chrome v8引擎的服务器端 JavaScript运行环境&#xff1b;Node. js是一个事件驱动、非阻塞式I/O的模型&#xff0c;轻量而又高效&#xff1b;Node. js的包管理器npm是全球最大的开源库生态系统。 2、数据处理中的buffer&#xff1a; 具体…...

Kotlin中泛型的协变

interface Shapeclass Circle : Shapefun main() {val shapes1: List<Shape> listOf<Circle>()val shapes2: MutableList<Shape> mutableListOf<Circle>() }如上代码&#xff0c;第一行赋值语句是OK的&#xff0c;第二行赋值语句在编辑器上直接就报错…...

第三百二十五节 Java线程教程 - Java Fork/Join框架

Java线程教程 - Java Fork/Join框架 fork/join框架通过利用机器上的多个处理器或多个内核来解决问题。 该框架有助于解决涉及并行性的问题。 fork/join框架创建一个线程池来执行子任务。 当线程在子任务上等待完成时&#xff0c;框架使用该线程来执行其他线程的其他未决子任…...

网络游戏安全现状及相关应对方案

中国网络游戏历经十余年的飞速发展&#xff0c;取得了显著成就&#xff0c;但与此同时&#xff0c;也陷入了诸多安全问题的泥沼。 一、中国网络游戏发展中的安全困境 &#xff08;一&#xff09;灰色产业链滋生 外挂、私服、盗号、打金工作室以及网络信息诈骗等灰色产业链在…...

uniapp h5地址前端重定向跳转

简单说下功能&#xff0c;就是在地址输入http://localhost:8080/home 会自行跳转到http://localhost:8080/pages/home/index&#xff0c;如果有带参数的话也会携带上去。 ps&#xff1a;只能在h5中使用 首先需要用到query-string 安装query-string npm install query-string…...

uniapp隐藏自带的tabBar

uniapp隐藏自带的tabBar 场景: 微信小程序在使用自定义tabBar组件时, 隐藏uniapp自带的tabBar <template> <!-- index页面 --> </template> <script setup> import { onShow } from /utils/wxUtils onShow(() > {uni.hideTabBar() // 隐藏自带的tab…...

使用--log-file保存pytest的运行日志

前面使用了tee和重定向来保存pytest的运行日志&#xff0c;这次使用--log-file&#xff0c;因为它可以配置日志的级别、格式和每行日志的生成时间。 pytest -q -s -ra --count100 test_open_stream.py --alluredir./report/CXL --log-filepytest_log.txt 【pytest.ini】 使用…...

WebAPI性能监控-MiniProfiler与Swagger集成

Net8_WebAPI性能监控-MiniProfiler与Swagger集成 要在.NET Core项目中集成MiniProfiler和Swagger&#xff0c;可以按照以下步骤操作&#xff1a; 安装NuGet包&#xff1a; 安装MiniProfiler.AspNetCore.Mvc包以集成MiniProfiler。安装MiniProfiler.EntityFrameworkCore包以监…...

视频会议接入GB28181视频指挥调度,语音对讲方案

传统的视频会议指挥调度系统目前主流的互联网会议大部分都是私有协议&#xff0c;功能都很独立。目前主流的视频监控国标都最GB平台&#xff0c;新的需求要求融合平台要接入监控等设备&#xff0c;并能实现观看监控接入会议&#xff0c;实时语音设备指挥现场工作人员办公实施。…...

深度学习和图像处理

看来你对深度学习和图像处理很感兴趣呢&#xff0c;让我来一一解答你的疑惑吧。 深度学习高纬度特征 首先&#xff0c;我猜你是想问“深度学习中的高维特征”吧。在深度学习中&#xff0c;随着网络层数的加深&#xff0c;网络的感受野逐渐变大&#xff0c;语义表达能力也随之增…...

〔 MySQL 〕数据类型

目录 1.数据类型分类 2 数值类型 2.1 tinyint类型 2.2 bit类型 2.3 小数类型 2.3.1 float 2.3.2 decimal 3 字符串类型 3.1 char 3.2 varchar 3.3 char和varchar比较 4 日期和时间类型 5 enum和set mysql表中建立属性列&#xff1a; 列名称&#xff0c;类型在后 n…...

云安全之云计算基础

0x00 前言 本文主要是针对云计算相关的基础梳理和整理。 云计算 NIST 800-145ISO/IEC 17788ISO/IEC 17789云安全 NIST 500-299 云安全ISO / IEC FDIS 27017 云安全0x01 云计算基础 什么是云计算: 一种新的运作模式和一组用于管理计算资源共享池的技术。云计算是一种颠覆性的…...

PostgreSQL pg-xact(clog)目录文件缺失处理

一、 背景 前些天晚上突然收到业务反馈&#xff0c;查询DB中的一个表报错 Could not open file "pg-xact/005E": No such file or directory. 两眼一黑难道是文件损坏了...登录查看DB日志&#xff0c;还好没有其他报错&#xff0c;业务也反馈只有这一个表在从库查询报…...

汽车生产虚拟实训中的技能提升与生产优化​

在制造业蓬勃发展的大背景下&#xff0c;虚拟教学实训宛如一颗璀璨的新星&#xff0c;正发挥着不可或缺且日益凸显的关键作用&#xff0c;源源不断地为企业的稳健前行与创新发展注入磅礴强大的动力。就以汽车制造企业这一极具代表性的行业主体为例&#xff0c;汽车生产线上各类…...

论文解读:交大港大上海AI Lab开源论文 | 宇树机器人多姿态起立控制强化学习框架(一)

宇树机器人多姿态起立控制强化学习框架论文解析 论文解读&#xff1a;交大&港大&上海AI Lab开源论文 | 宇树机器人多姿态起立控制强化学习框架&#xff08;一&#xff09; 论文解读&#xff1a;交大&港大&上海AI Lab开源论文 | 宇树机器人多姿态起立控制强化…...

GitHub 趋势日报 (2025年06月08日)

&#x1f4ca; 由 TrendForge 系统生成 | &#x1f310; https://trendforge.devlive.org/ &#x1f310; 本日报中的项目描述已自动翻译为中文 &#x1f4c8; 今日获星趋势图 今日获星趋势图 884 cognee 566 dify 414 HumanSystemOptimization 414 omni-tools 321 note-gen …...

实现弹窗随键盘上移居中

实现弹窗随键盘上移的核心思路 在Android中&#xff0c;可以通过监听键盘的显示和隐藏事件&#xff0c;动态调整弹窗的位置。关键点在于获取键盘高度&#xff0c;并计算剩余屏幕空间以重新定位弹窗。 // 在Activity或Fragment中设置键盘监听 val rootView findViewById<V…...

【HarmonyOS 5 开发速记】如何获取用户信息(头像/昵称/手机号)

1.获取 authorizationCode&#xff1a; 2.利用 authorizationCode 获取 accessToken&#xff1a;文档中心 3.获取手机&#xff1a;文档中心 4.获取昵称头像&#xff1a;文档中心 首先创建 request 若要获取手机号&#xff0c;scope必填 phone&#xff0c;permissions 必填 …...

C++使用 new 来创建动态数组

问题&#xff1a; 不能使用变量定义数组大小 原因&#xff1a; 这是因为数组在内存中是连续存储的&#xff0c;编译器需要在编译阶段就确定数组的大小&#xff0c;以便正确地分配内存空间。如果允许使用变量来定义数组的大小&#xff0c;那么编译器就无法在编译时确定数组的大…...

腾讯云V3签名

想要接入腾讯云的Api&#xff0c;必然先按其文档计算出所要求的签名。 之前也调用过腾讯云的接口&#xff0c;但总是卡在签名这一步&#xff0c;最后放弃选择SDK&#xff0c;这次终于自己代码实现。 可能腾讯云翻新了接口文档&#xff0c;现在阅读起来&#xff0c;清晰了很多&…...

脑机新手指南(七):OpenBCI_GUI:从环境搭建到数据可视化(上)

一、OpenBCI_GUI 项目概述 &#xff08;一&#xff09;项目背景与目标 OpenBCI 是一个开源的脑电信号采集硬件平台&#xff0c;其配套的 OpenBCI_GUI 则是专为该硬件设计的图形化界面工具。对于研究人员、开发者和学生而言&#xff0c;首次接触 OpenBCI 设备时&#xff0c;往…...

tomcat入门

1 tomcat 是什么 apache开发的web服务器可以为java web程序提供运行环境tomcat是一款高效&#xff0c;稳定&#xff0c;易于使用的web服务器tomcathttp服务器Servlet服务器 2 tomcat 目录介绍 -bin #存放tomcat的脚本 -conf #存放tomcat的配置文件 ---catalina.policy #to…...

TSN交换机正在重构工业网络,PROFINET和EtherCAT会被取代吗?

在工业自动化持续演进的今天&#xff0c;通信网络的角色正变得愈发关键。 2025年6月6日&#xff0c;为期三天的华南国际工业博览会在深圳国际会展中心&#xff08;宝安&#xff09;圆满落幕。作为国内工业通信领域的技术型企业&#xff0c;光路科技&#xff08;Fiberroad&…...