c++类和对象(2)

1. 类的6个默认成员函数

在C++中,如果一个类没有显式定义某些成员函数,编译器会默认为这个类生成六个默认成员函数。以下是这六个默认成员函数:

默认构造函数(Default Constructor)

如果类没有定义任何构造函数,编译器会提供一个默认构造函数,这个默认构造函数是一个无参构造函数,它的作用是创建一个对象,并为对象的成员变量提供默认值。

析构函数(Destructor)

如果类没有定义析构函数,编译器会提供一个默认的析构函数,默认析构函数是一个空函数体,用于在对象生命周期结束时释放资源。

拷贝构造函数(Copy Constructor)

用于通过一个同类型的已存在对象来初始化一个正在创建的对象。默认的拷贝构造函数执行成员的逐位复制。

拷贝赋值运算符(Copy Assignment Operator)

用于将一个对象赋值给同类型的另一个已存在对象。默认的拷贝赋值运算符执行成员的逐位赋值。

移动构造函数(Move Constructor) (C++11及以后)

当需要通过一个临时对象来初始化同类型的另一个对象时,移动构造函数会被调用。默认的移动构造函数“窃取”临时对象的资源。

移动赋值运算符(Move Assignment Operator) (C++11及以后)

用于将一个临时对象赋值给同类型的另一个已存在对象。默认的移动赋值运算符也是“窃取”临时对象的资源。

2. 构造函数

构造函数是类的一个特殊成员函数,它的主要作用是在创建类的对象时初始化对象的成员变量。构造函数具有以下特点:

  1. 函数名称:构造函数的名称必须与类名相同。
  2. 参数:构造函数可以没有参数,也可以有多个参数,用于提供初始化成员变量的值。
  3. 返回类型:构造函数没有返回类型,即使是void也不可以。
  4. 作用:在对象创建时自动调用,用于初始化对象的成员变量。

默认构造函数

如果类没有定义任何构造函数,编译器会提供一个默认构造函数。如果定义了其他构造函数,但仍然需要一个无参的构造函数,则必须显式定义默认构造函数。

class MyClass {
public:MyClass() {// 默认构造函数的实现}
};

 参数化构造函数

允许在创建对象时传递参数,以初始化对象的成员变量。

class MyClass {
public:int x;MyClass(int val) : x(val) {// 参数化构造函数的实现}
};

 转换构造函数

允许通过一个不同类型的值来创建对象。

class MyClass {
public:MyClass(int val) {// 转换构造函数的实现}
};

 初始化列表

构造函数可以使用初始化列表来初始化成员变量,这通常比在函数体内赋值更高效。

class MyClass {
public:int x;MyClass() : x(10) {// 使用初始化列表}
};

3. 析构函数

析构函数是类的一个特殊成员函数,它的作用是在对象生命周期结束时执行必要的清理工作。析构函数具有以下特点:

  1. 函数名称:析构函数的名称是在类名前加上波浪号(~)。
  2. 参数:析构函数没有参数,因此不能被重载。
  3. 返回类型:析构函数没有返回类型,即使是void也不可以。
  4. 作用:在对象被销毁时自动调用,用于释放对象所占用的资源,如动态分配的内存、打开的文件句柄、网络连接等。

规则

  • 每个类只能有一个析构函数。
  • 如果类没有显式定义析构函数,编译器会自动生成一个默认的析构函数,该默认析构函数是一个空函数体。
  • 如果类中包含指向动态分配内存的指针成员,则通常需要定义一个自定义的析构函数来释放这些内存。
class MyClass {
public:MyClass() {// 构造函数的实现,可能包含动态内存分配}~MyClass() {// 析构函数的实现,释放动态分配的内存}
private:int* data; // 指向动态分配内存的指针
};int main() {MyClass obj; // 创建对象,调用构造函数// ... 使用对象 ...return 0; // 程序结束,obj对象生命周期结束,调用析构函数
}

4. 拷贝构造函数

拷贝构造函数是一种特殊的构造函数,它用于创建一个新对象作为另一个同类对象的副本。拷贝构造函数具有以下特点:

  1. 函数名称:拷贝构造函数的名称与类名相同,且有一个参数,该参数是对类类型对象的引用。
  2. 参数:拷贝构造函数的参数必须是类类型的引用,通常使用常量引用,以避免修改原对象,并允许传递临时对象。
  3. 返回类型:拷贝构造函数没有返回类型,即使是void也不可以。
  4. 作用:当需要通过已存在的对象来初始化一个新对象时,拷贝构造函数会被调用。
class MyClass {
public:MyClass(const MyClass& other) {// 拷贝构造函数的实现// 通常用于复制成员变量}// 其他成员函数和成员变量...
};

默认拷贝构造函数

如果类没有显式定义拷贝构造函数,编译器会自动生成一个默认的拷贝构造函数。默认拷贝构造函数执行成员的逐位复制(浅拷贝)。对于包含指针成员的类,默认拷贝构造函数可能会导致问题,因为它只会复制指针的值,而不是指针指向的数据。

自定义拷贝构造函数

在某些情况下,需要自定义拷贝构造函数来执行深拷贝,以确保每个对象都有自己独立的副本。

class MyClass {
public:int* data;MyClass(int value) : data(new int(value)) {}// 自定义拷贝构造函数MyClass(const MyClass& other) : data(new int(*other.data)) {// 执行深拷贝}~MyClass() {delete data; // 释放动态分配的内存}
};

5. 赋值运算符重载

在C++中,赋值运算符 = 可以被重载以定制对象之间的赋值行为。当你定义了一个类,并且希望对象能够使用 = 运算符进行赋值时,你可能需要重载赋值运算符。

  1. 参数类型:赋值运算符重载函数应该有一个参数,该参数是类类型的引用。通常使用常量引用,以允许传递临时对象,并防止在赋值过程中修改右操作数。

  2. 返回类型:赋值运算符重载函数应该返回一个指向当前对象的引用,通常是一个 *this 指针。

  3. 函数名称:赋值运算符重载的函数名是 operator=

  4. 成员函数:赋值运算符必须是类的成员函数。

class MyClass {
public:int* data;MyClass(int value) : data(new int(value)) {}// 赋值运算符重载MyClass& operator=(const MyClass& other) {if (this != &other) { // 避免自我赋值delete data;      // 删除旧值data = new int(*other.data); // 深拷贝}return *this; // 返回当前对象的引用}~MyClass() {delete data; // 析构函数中释放动态分配的内存}
};

 

注意事项:

  • 自我赋值检查:在赋值运算符的实现中,检查自我赋值是非常重要的,以避免在释放内存后使用悬空指针。
  • 资源管理:如果类管理动态分配的资源,赋值运算符应该正确地管理这些资源,避免内存泄漏和悬挂指针。
  • 返回值:赋值运算符应该返回当前对象的引用,这允许链式赋值,例如 a = b = c;

6. const成员函数

在C++中,const成员函数是指那些承诺不修改调用对象的数据成员的函数。当你声明一个成员函数为const时,你告诉编译器这个函数不会改变对象的任何成员变量(非静态成员变量)。这是通过在函数声明和定义后面加上const关键字来实现的。

class MyClass {
public:void normalFunction() {// 可以修改成员变量}void constFunction() const {// 不能修改成员变量}
};

 

注意事项

  • const成员函数内部,你不能修改任何非静态成员变量。
  • 你可以修改静态成员变量和局部变量,因为这些变量不与对象的状态直接相关。
  • 你可以在const成员函数内部调用其他非const成员函数,但前提是这些函数不修改任何非静态成员变量。

7. 取地址及const取地址操作符重载

在C++中,你可以重载几种特殊的成员操作符,包括取地址操作符 & 和 const 取地址操作符 const &。虽然这些操作符通常不需要重载,因为编译器默认提供的版本就已经足够使用,但在某些特殊情况下,你可能需要自定义它们的行为。

重载取地址操作符 &

class MyClass {
public:// 重载取地址操作符MyClass* operator&() {// 返回当前对象的地址return this;}
};

重载const取地址操作符 const &

class MyClass {
public:// 重载const取地址操作符const MyClass* operator&() const {// 返回当前对象的const地址return this;}
};

注意事项

  • 重载取地址操作符通常不是一个好主意,因为这可能会导致混淆和意外的行为。通常,编译器提供的默认行为是正确的,即返回对象的实际地址。
  • 如果你确实重载了这些操作符,它们必须返回指向类类型的指针。对于 const 版本,返回类型应该是指向 const 类型的指针。
  • 重载这些操作符的返回类型不能是引用类型,因为地址操作符的预期行为是返回一个指针。
  • 重载这些操作符的目的是为了改变它们的行为,但通常不建议这样做,除非你有非常特殊的需求。

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

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

jdk各个版本介绍

Java Development Kit(JDK)是Java平台的核心组件,它包含了Java编程语言、Java虚拟机(JVM)、Java类库以及用于编译、调试和运行Java应用程序的工具。 JDK 1.0-1.4(经典时代) • JDK 1.0&#xff…

【Python爬虫五十个小案例】爬取猫眼电影Top100

博客主页:小馒头学python 本文专栏: Python爬虫五十个小案例 专栏简介:分享五十个Python爬虫小案例 🐍引言 猫眼电影是国内知名的电影票务与资讯平台,其中Top100榜单是影迷和电影产业观察者关注的重点。通过爬取猫眼电影Top10…

Doge东哥wordpress主题

Doge东哥wordpress主题是一款专为中小型企业设计的WordPress外贸网站模板,它以其现代、专业且用户友好的界面,为企业提供了一个展示产品和服务的理想平台。以下是对该模板的详细描述: 首页设计概览 首页的设计简洁而不失大气,顶…

【力扣】541.反转字符串2

问题描述 思路解析 每当字符达到2*k的时候,判断,同时若剩余字符>k,只对前k个进行判断(这是重点)因为字符串是不可变变量,所以将其转化为字符串数组,最后才将结果重新转变为字符串 字符串->字符数组 …

C++练级计划-> 《IO流》iostream fstream sstream详解

如果是想全部过一遍就看完,如果想具体的了解某一个请点目录。因为有三种流的使用可能内容多 目录 流是什么? CIO流(iostream) io流的注意事项 cin和cout为什么能直接识别出类型和数据 fstream fstream的使用方法&#xff…

EDA软件研发的DevOps平台

1:什么是DevOps DevOps是十几年前,在互联网比较火的词,实际上就是ci/cd平台的另外一种说法,核心是说打破研发,测试,运维的边界,能够将整个产品开发的流程快速循环起来,随时可发版&a…

自动化是语法,智能化是语义与语用

自动化与智能化可以从语言学的角度来进行类比和探讨。 1. 自动化是语法 自动化可以类比为“语法”的部分,因为它关注的是操作过程的规则、结构和执行方式。语法是语言中关于词汇、句子结构和规则的系统,它提供了语言运作的框架和规范。类似地&#xff0c…

Spring源码-Bean的生命周期和模板方法

Bean的生命周期 之前我们提到过SpringApplication的run方法不光可以启动程序,还会返回一个容器,为了演示Bean的从创建到销毁的整个阶段,我们会关闭掉容器。 接下来我们来看想要加入到容器当中的类,映入眼帘的是这几个方法和其注解…

Mysql数据库基础篇笔记

目录 sql语句 DDL——数据库定义语言(定义库,表,字段) 数据库操作: 表操作: DML 增删改语句 DQL 语法编写顺序: 条件查询 DCL 用户管理: 权限管理: 函数 常见字符串内置函…

算法编程题-煎饼排序 不含AAA或者BBB的字符串

算法编程题-煎饼排序 &&不含AAA或者BBB的字符串 煎饼排序原题描述思路简述代码实现复杂度分析 不含AAA或者BBB的字符串原题描述思路简述代码实现复杂度分析 摘要:本文将对两道LeetCode原题进行介绍,分别是煎饼排序和不含AAA或者BBB的字符串。在陈…

分享一款 Vue 图片编辑插件 (推荐)

💥本篇文章给大家分享一款强大到没朋友的Vue图片编辑插件,可以对图片进行旋转、缩放、裁剪、涂鸦、标注、添加文本等,快来试试并收藏吧!💕 这是一款对图片进行旋转、缩放、裁剪、涂鸦、标注、添加文本在线处理的图片处…

MySQL 核心基础 | Pandaer杂货铺

MySQL一个后端开发必须会接触的中间件,也是关系型数据库的代表。如果你希望看下去这篇文章,需要你有使用MySQL或者相关关系型数据库的经验,不然这篇文章在你眼中就会索然无味了。 这篇文章不会讲解如何使用MySQL,例如如何安装&am…

【网络】应用层协议HTTPHTTPcookie与sessionHTTPS协议原理

主页:醋溜马桶圈-CSDN博客 专栏:计算机网络原理_醋溜马桶圈的博客-CSDN博客 gitee:mnxcc (mnxcc) - Gitee.com 目录 1.应用层协议HTTP 2.认识 URL 2.1 urlencode 和 urldecode 3.HTTP 协议请求与响应格式 3.1 HTTP 请求 3.2 HTTP 响应 …

搭建业务的性能优化指南

这是一篇搭建业务优化的心路历程,也是写给搭建业务的性能优化指南。 前言 直到今天,淘内的页面大多都迁移到了 SSR,从我们终端平台 - 搭建研发团队的视角看,业务大致可以分为两类 —— 搭建派 和 源码派。 这两者互不冲突&#xf…

Swift实现高效链表排序:一步步解读

文章目录 前言摘要问题描述题解解题思路Swift 实现代码代码分析示例测试与结果 时间复杂度空间复杂度总结关于我们 前言 本题由于没有合适答案为以往遗留问题,最近有时间将以往遗留问题一一完善。 148. 排序链表 不积跬步,无以至千里;不积小流…

开源 - Ideal库 - Excel帮助类,TableHelper实现(三)

书接上回,我们今天继续讲解实现对象集合与DataTable的相互转换。 01、把表格转换为对象集合 该方法是将表格的列名称作为类的属性名,将表格的行数据转为类的对象。从而实现表格转换为对象集合。同时我们约定如果类的属性设置了DescriptionAttribute特性…

基于DHCP,ACL的通信

该问题为华为的学习资料 1.首先把所有的PC机全部设置为DHCP 2.配置地址 3.ospf 4.dhcp 5.acl AR1 dhcp en interface GigabitEthernet0/0/0ip address 192.168.1.254 255.255.255.0 dhcp select global interface GigabitEthernet0/0/1ip address 10.1.12.1 255.255.255.…

基于深度学习的卷积神经网络十二生肖图像识别系统(PyQt5界面+数据集+训练代码)

本研究提出了一种基于深度学习的十二生肖图像识别系统,旨在利用卷积神经网络(CNN)进行图像分类,特别是十二生肖图像的自动识别。系统的核心采用了两种经典的深度学习模型:ResNet50和VGG16,进行图像的特征提…

探索温度计的数字化设计:一个可视化温度数据的Web图表案例

随着科技的发展,数据可视化在各个领域中的应用越来越广泛。在温度监控和展示方面,传统的温度计已逐渐被数字化温度计所取代。本文将介绍一个使用Echarts库创建的温度计Web图表,该图表通过动态数据可视化展示了温度值,并通过渐变色…

Attention显存统计与分析

Attention显存估计 简单的Attention函数 import torch import torch.nn as nn import einops class Attention(nn.Module):def __init__(self, dim, num_heads8, qkv_biasFalse, qk_scaleNone, attn_drop0., proj_drop0.):super().__init__()self.num_heads num_headshead_d…