类与对象(2)---类的6个默认成员函数

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

任何类在什么都不写时,编译器会自动生成以下6个默认成员函数
默认成员函数:用户没有显式实现,编译器会生成的成员函数称为默认成员函数。


 2.构造函数

2.1构造函数特性

构造函数的主要任务是初始化对象

它有如下特征: 

1. 函数名与类名相同。

2. 无返回值。

3. 对象实例化时编译器自动调用对应的构造函数。

4. 构造函数可以重载。 

class Date
{
 public:
     //1.无缺省
     // (1)无参构造函数
     Date()
     {}
 
     // 2.带参构造函数
     Date(int year, int month, int day)
     {
         _year = year;
         _month = month;
         _day = day;
     }
    //eg:
    Date d1();
    *1*函数重载的语法支持;*2*编译器会存在歧义,认为其是函数声明

    /*
    //2.全缺省
    如果是全缺省的构造函数,
    只Date d1;都会存在歧义

    Date()
     {}
    
    Date(int year = 2022, int month = 6, int day = 4)
    {
        _year = year;
         _month = month;
         _day = day;
    }
    */

 private:
     int _year;
     int _month;
     int _day;
};
 
 void TestDate()
{
     Date d1; // 调用无参构造函数
     Date d2(2015, 1, 1); // 调用带参的构造函数
 
     // 注意:如果通过无参构造函数创建对象时,对象后面不用跟括号,否则就成了函数声明
     // 以下代码的函数:声明了d3函数,该函数无参,返回一个日期类型的对象
     // warning C4930: “Date d3(void)”
     Date d3();//错误
}

5. 如果类中没有显式定义构造函数,则C++编译器会自动生成一个无参的默认构造函数,一旦用户显式定义编译器将不再生成。

6.编译器生成的默认构造函数作用

C++把类型分成内置类型(基本类型)和自定义类型

内置类型/基本类型:语言本身定义的基础类型,包括 int / char / double 等等。

自定义类型:用 class / struct 等等定义的类型。

注意

我们不写,编译器会默认生成的构造函数内置类型不做处理自定义类型会去调用它的默认构造函数

有些编译器也会处理,但是那是个性化行为,并不是所有的编译器都会处理。

 注意:C++11 中针对内置类型成员不初始化的缺陷,又打了补丁,即:内置类型成员变量
类中声明时可以给默认值

class Time
{
public:
    Time()
    {
    cout << "Time()" << endl;
    _hour = 0;
    _minute = 0;
    _second = 0;
    }

private:
    int _hour;
    int _minute;
    int _second;
};

class Date
{
private:
    // 基本类型(内置类型)
    int _year = 1970;
    int _month = 1;
    int _day = 1;

    // 自定义类型
    Time _t;
};

int main()
{
    Date d;
    //利用监视可查看
    return 0;
}

7. 无参的构造函数和全缺省的构造函数都称为默认构造函数,默认构造函数只能有一个


注意无参构造函数全缺省构造函数、我们没写编译器默认生成的构造函数,都可以认为
默认构造函数。 

所以,

(1)一般情况下,有内置类型成员,就需要自己写构造函数,不能用编译器自己生成的。

(2)全部都是自定义类型成员,可以考虑让编译器自己生成。


 结论:

1.一般情况下,构造函数都需要我们自己写

2.以下情况可用自动生成的默认构造:

a.内置类型成员都有缺省值,且初始化符合我们的要求。      

b.全是自定义类型的构造,且这些类型都定义默认构造

2.2代码仓库

gitee/jimmywang16/learn_1/class_object1112/构造函数


3.析构函数

 3.1析构函数特性

1. 析构函数名是在类名前加上字符 ~
2. 无参数无返回值类型。
3. 一个类只能有一个析构函数。若未显式定义,系统会自动生成默认的析构函数。

注意:析构函数不能重载
4. 对象生命周期结束时,C++编译系统系统自动调用析构函数。

5.编译器
生成的默认析构函数,对自定类型成员调用它的析构函数。

6.如果类中没有申请资源时,析构函数可以不写,直接使用编译器生成的默认析构函数,比如Date类;有资源申请时,一定要写,否则会造成资源泄漏,比如Stack类。



4.拷贝构造函数

4.1拷贝构造函数特征

1. 拷贝构造函数是构造函数的一个重载形式。

2. 拷贝构造函数的参数只有一个且必须是类类型对象的引用,使用传值方式编译器直接报错,因为会引发无穷递归调用。

Date(const Date& d)
{
	cout << "use Date(const Date& d)" << endl;
	_year = d._year;
	_month = d._month;
	_day = d._day;
}

3. 若未显式定义,编译器会生成默认的拷贝构造函数。 默认的拷贝构造函数对象按内存存储按字节序完成拷贝,这种拷贝叫做浅拷贝,或者值拷贝。

4. 编译器生成的默认拷贝构造函数已经可以完成字节序的值拷贝了。

总结:

C++内置类型直接拷贝,自定义类型传参必须调用拷贝构造完成拷贝

 5. 拷贝构造函数典型调用场景
使用已存在对象创建新对象;
函数参数类型为类类型对象;
函数返回值类型为类类型对象;

class Date
{
public:

	Date(int year = 1, int month = 1, int day = 1)
	{
		_year = year;
		_month = month;
		_day = day;
	}

	Date(const Date& d)
	{
		cout << "use Date(const Date& d)" << endl;
		_year = d._year;
		_month = d._month;
		_day = d._day;
	}

private:
	int _year;
	int _month;
	int _day;
};


int main()
{
	Date d1(2024, 2, 26);
	Date d2(d1);

	return 0;
}

5.赋值运算符重载

5.1.运算符重载

class Date
{
public:

	Date(int year = 1, int month = 1, int day = 1)
	{
		_year = year;
		_month = month;
		_day = day;
	}
	bool operator<(const Date& x)
	{
		if (_year < x._year)
		{
			return false;
		}
		else if (_year == x._year && _month < x._month)
		{
			return false;
		}
		else if (_year == x._year && _month == x._month && _day < x._day)
		{
			return true;
		}
		return false;
	}
private:
	int _year;
	int _month;
	int _day;
};
int main()
{
	
	d1 < d2;    //等价于下方
	d1.operator<(d2);
	return 0;
}

私有怎么办?——写到类的内部:

bool operator<(const Date& x)
{
	if (_year < x._year)
	{
		return false;
	}
	else if (_year == x._year && _month < x._month)
	{
		return false;
	}
	else if (_year == x._year && _month == x._month && _day < x._day)
	{
		return true;
	}

	return false;
}

5.2赋值运算符重载

class Date
{
public :
   Date(int year = 1900, int month = 1, int day = 1)
   {
       _year = year;
       _month = month;
       _day = day;
   }
   Date (const Date& d)
   {
       _year = d._year;
       _month = d._month;
       _day = d._day;
   }
   Date& operator=(const Date& d)
   {
   if(this != &d)
   {
       _year = d._year;
       _month = d._month;
       _day = d._day;
   }
       
    return *this;
}
private:
    int _year ;
    int _month ;
    int _day ;
};

 

******************重点区分******************

 5.3前置++和后置++重载

5.4代码仓库

gitee/jimmywang16/learn_1/learn1113/赋值运算符重载及其相关


5.5 cout,cin

运算符重载是让自定义类型支持运算符;

两个运算符重载构成函数重载。

6.const成员

6.1用法

将const修饰的“成员函数”称之为const成员函数,const修饰类成员函数,实际修饰该成员函数
隐含的this指针(*this),表明在该成员函数中不能对类的任何成员进行修改(不能对this指向的内容进行修改,+、-、>、<、==、... 需加const)

权限的放大

本质:const Date* const this 

this本身不能被修改,this指向的内容也不能被修改。

注意:

const加在——不需要修改——对象成员变量的函数。

class Date
{
public:
    //...
    bool operator<(const Date& x) const;
    bool operator==(const Date& x) const;
    bool operator<=(const Date& x) const;
    bool operator>(const Date& x) const;
    bool operator>=(const Date& x) const;
    bool operator!=(const Date& x) const;

    static int Getmonthdays(int year, int month);
    Date& operator+=(int days);
    Date operator+(int days) const;

    Date& operator++();
    Date operator++(int);

    Date& operator-=(int days);
    Date operator-(int days) const;

    Date& operator--();
    Date operator--(int);
    //...
    int operator-(const Date& d) const;

    void Print() const // const加在不需要修改——对象成员变量的函数
    {
	    cout << _year << " / " << _month << " / " << _day << endl;
    }
private:
    //...
}

6.2易混淆

6.3代码仓库

learn1113/运算符重载、Date日期类和const成员


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

这两个默认成员函数一般不用重新定义编译器默认会生成

class Date
{
public :
    Date* operator&()
    {
        return this ;
    }

    const Date* operator&()const
    {
        return this ;
    }
private :
    int _year ; // 年
    int _month ; // 月
    int _day ; // 日
};

这两个运算符一般不需要重载,使用编译器生成的默认取地址的重载即可,只有特殊情况,才需
要重载,比如想让别人获取到指定的内容!

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

[OpenGL]使用OpenGL实现透明效果

一、简介 本文介绍了如何使用OpenGL实现透明效果&#xff08;transparent&#xff09;&#xff0c;并在最后给出了全部的代码。 在实现透明效果时&#xff0c;使用OpenGL中的混合&#xff08;Blend&#xff09;功能&#xff0c;根据纹理贴图的 alpha 分量将各像素&#xff08;…

【实用技能】ASP.NET Core:在同一个 Razor 视图中使用文档编辑器和查看器

Essential Studio for ASP.NET Core UI控件库是构建应用程序所需的卓越套件&#xff0c;提供支持的 ASP.NET Core 工具包拥有超过 85 个组件&#xff0c;包含构建业务线应用程序所需的一切&#xff0c;包括数据网格、图表、甘特图、图表、电子表格、时间表、数据透视网格等流行…

Android从Drawable资源Id直接生成Bitmap,Kotlin

Android从Drawable资源Id直接生成Bitmap,Kotlin val t1 System.currentTimeMillis()val bmp getBmpFromDrawId(this, R.mipmap.ic_launcher_round)Log.d("fly", "1 ${bmp?.byteCount} h${bmp?.height} w${bmp?.width} cost time${System.currentTimeMillis…

【JavaScript】LeetCode:96-100

文章目录 96 单词拆分97 最长递增子序列98 乘积最大子数组99 分割等和子集100 最长有效括号 96 单词拆分 动态规划完全背包&#xff1a;背包-字符串s&#xff0c;物品-wordDict中的单词&#xff0c;可使用多次。问题转换&#xff1a;s能否被wordDict中的单词组成。dp[i]&#x…

【扩散——BFS】

题目 代码 #include <bits/stdc.h> using namespace std; const int t 2020, off 2020; #define x first #define y second typedef pair<int, int> PII; int dx[] {0, 0, 1, -1}, dy[] {-1, 1, 0, 0}; int dist[6080][6080]; // 0映射到2020&#xff0c;2020…

柯桥生活英语口语学习“面坨了”英语怎么表达?

“面坨了”英语怎么表达&#xff1f; 要想搞清楚这个表达&#xff0c;首先&#xff0c;我们要搞明白“坨”是啥意思&#xff1f; 所谓“坨”就是指&#xff0c;面条在汤里泡太久&#xff0c;从而变涨&#xff0c;黏糊凝固在一起的状态。 有一个词汇&#xff0c;很适合用来表达这…

IOT物联网低代码可视化大屏解决方案汇总

目录 参考来源云服务商阿里云物联网平台产品主页产品文档 开源项目DGIOT | 轻量级工业物联网开源平台项目特点项目地址开源许可 IoTGateway | 基于.NET6的跨平台工业物联网网关项目特点项目地址开源许可 IoTSharp | 基于.Net Core开源的物联网基础平台项目特点项目地址开源许可…

CSP-X2024山东小学组T2:消灭怪兽

题目链接 题目名称 题目描述 怪兽入侵了地球&#xff01; 为了抵抗入侵&#xff0c;人类设计出了按顺序排列好的 n n n 件武器&#xff0c;其中第 i i i 件武器的攻击力为 a i a_i ai​&#xff0c;可以造成 a i a_i ai​ 的伤害。 武器已经排列好了&#xff0c;因此不…

信息收集—JS框架识别泄露提取API接口泄露FUZZ爬虫插件项目

前言 免杀结束了&#xff0c;我们开个新的篇章——信息收集。为什么我一开始先写信息收集的文章呢&#xff0c;是因为现在我才发现我的信息收集能力其实有点弱的&#xff0c;所以呢开始知不足&#xff0c;而后进。 什么是JS JS就是JavaScript的简称&#xff0c;它和Java是没…

性能调优专题(9)之从JDK源码级别解析JVM类加载机制

一、类加载运行全过程 当我们用java命令运行某个类的main函数启动程序时&#xff0c;首先需要通过类加载器把主类加载到JVM。 package com.tuling.jvm;public class Math {public static final int initData 666;public static User user new User();public int compute() {…

Gin 框架入门(GO)-1

解决安装包失败问题&#xff08;*&#xff09; go env -w GO111MODULEon go env -w GOPROXYhttps://goproxy.cn,direct 1 介绍 Gin 是一个 Go (Golang) 编写的轻量级 http web 框架&#xff0c;运行速度非常快&#xff0c;Gin 最擅长的就是 Api 接口的高并发。 2 Gin 环境搭建…

Python如何从HTML提取img标签下的src属性

目录 前提准备步骤1. 解析HTML内容2. 查找所有的img标签3. 提取src属性 完整代码 前提准备 在处理网页数据时&#xff0c;我们经常需要从HTML中提取特定的信息&#xff0c;比如图片的URL。 这通常通过获取img标签的src属性来实现。 在开始之前&#xff0c;你需要确保已经安装…

web——upload-labs——第五关——大小写绕过绕过

先上传一个 先尝试直接上传一个普通的一句话木马 不行 可以看到&#xff0c;.htaccess文件也被过滤了&#xff0c;我们来查看一下源码 第五关的源码没有把字符强制转换为小写的语句&#xff1a; $file_ext strtolower($file_ext); //转换为小写 直接通过Burpsuite抓包修改文…

C#/WinForm拖拽文件上传

一、首先创建一个上传文件的类&#xff0c;继承Control类&#xff0c;如下&#xff1a; public class UploadControl : Control{private Image _image;public UploadControl(){this.SetStyle(ControlStyles.UserPaint | //控件自行绘制&#xff0c;而不使用操作系统的绘制Cont…

oracle查询字段类型长度等字段信息

1.查询oracle数据库的字符集 SELECT * FROM NLS_DATABASE_PARAMETERS WHERE PARAMETER NLS_CHARACTERSET; 2.查询字段长度类型 SELECT * FROM user_tab_columns WHERE table_name user AND COLUMN_NAME SNAME 请确保将user替换为您想要查询的表名。sname为字段名 这里的字…

大模型基础BERT——Transformers的双向编码器表示

大模型基础BERT——Transformers的双向编码器表示 整体概况 BERT&#xff1a;用于语言理解的深度双向Transform的预训练 论文题目&#xff1a;BERT: Pre-training of Deep Bidirectional Transformers for Language Understanding Bidirectional Encoder Representations from…

Ceph层次架构分析

Ceph的层次结构可以从逻辑上自下向上分为以下几个层次&#xff1a; 一、基础存储系统RADOS层 功能&#xff1a;RADOS&#xff08;Reliable Autonomic Distributed Object Store&#xff09;是Ceph的底层存储系统&#xff0c;提供了分布式存储的核心功能。它是一个完整的对象存…

实验6记录网络与故障排除

实验6记录网络与故障排除 实验目的及要求&#xff1a; 通过实验&#xff0c;掌握如何利用文档记录网络设备相关信息并完成网络拓扑结构的绘制。能够使用各种技术和工具来找出连通性问题&#xff0c;使用文档来指导故障排除工作&#xff0c;确定具体的网络问题&#xff0c;实施…

【前端】技术演进发展简史

一、前端 1、概述 1990 年&#xff0c;第一个web浏览器诞生&#xff0c;Tim 以超文本语言 HTML 为基础在 NeXT 电脑上发明了最原始的 Web 浏览器。 1991 年&#xff0c;WWW诞生&#xff0c;这标志着前端技术的开始。 前端&#xff08;Front-end&#xff09;和后端&#xff08;…

【笔记】关于git和GitHub和git bash

如何推送更新的代码到github仓库 如何在此项目已经提交在别的远程仓库的基础上更改远程仓库地址&#xff08;也就是换一个远程仓库提交&#xff09; 如何删除github中的一个文件 第二版 删除github上的一个仓库或者仓库里面的某个文件_github仓库删除一个文件好麻烦-CSDN博客 …