类和对象(3)

博客ID:LanFuRen
C系列专栏C语言重点部分  C语言注意点  C++基础  Linux  数据结构  C++注意点
声明等级:黑色->蓝色->红色
欢迎新粉加入,会一直努力提供更优质的编程博客,希望大家三连支持一下啦

目录

1.拷贝构造

2.传值返回和传引用返回用法

3.运算符重载&赋值重载

 前置++与后置++问题

const 修饰的成员函数

4.手撕日期类


1.拷贝构造

在了解拷贝构造之前,我们先来把普通构造函数总结一下:

构造函数是对对象(对象的成员变量)进行初始化;

自定义类型会自动调用默认构造函数(在我们没有写出构造函数的情况下),内置类型不一定会调用构造函数,这得看编译器的处理了,所以我们可以给内置类型成员变量给缺省值;

默认构造函数包括:无参构造函数、全缺省构造函数、我们没写编译器默认生成的构造函数。

拷贝构造也是构造函数的一种,只不过是将已经初始化的对象拷贝给未初始化的对象,达到拷贝(初始化)的效果。

//Date.h
#pragma once
#include<iostream>
using namespace std;
class Date
{
public:
	Date(int year=1, int month=1, int day=1)
	{
		_year = year;
		_month = month;
		_day = day;
	}

	void Print()
	{
		cout << _year << "-" << _month << "-" << _day << endl;
	}
private:
	int _year;
	int _month ;
	int _day ;
};
//Date.c
#include"C++5.h"
int main()
{
	//缺省+
	Date d1(2024);
	//拷贝构造
	//用同类型的对象拷贝初始化
	//1
	Date d2(d1);
    //Date d2=d1;这是拷贝构造调用第二种形式
	d1.Print();
	d2.Print();
	return 0;
}

运行结果: 

 浅(值)拷贝与深拷贝:

在使用拷贝构造时,我们需要鉴别是否需要显示写出拷贝构造,显示拷贝构造就是深拷贝。如果出现malloc的空间,我们默认拷贝的参数是直接传值,把值拷贝过去;如果我们只传入指针的值(存放数组的地址),那我们新对象d2和旧对象d1就会共用同一个数组空间(因为都是同一个数组的地址),那样修改d1就会影响d2,反之亦然。

我们举个例子写出深拷贝的写法:

class MyClass {
private:
    int* data;
public:
    MyClass(int value) {
        data = new int(value);
    }
    ~MyClass() {
        delete data;
    }
    MyClass(const MyClass& other) {
        data = new int(*other.data);
    }
};

2.传值返回和传引用返回用法

 第一个函数func的返回值是Date,返回d时会拷贝构造生成一个临时变量,可以理解成Date tmp=d;因为临时变量具有常性,接收的时候需要用const修饰,防止权限的放大。接收的时候相当于const Date&ref=tmp;如果写成const Date ref=tmp那也是一次拷贝构造,只不过用&之后是tmp的别名,不会调用拷贝构造。

第二个人就是引用返回,会减少这第一个箭头的拷贝构造。

但是传值传引用各有利弊,如果return返回的不是指针,malloc,new等开的空间,那么就相当于野指针的出现(野引用)

两者的使用主要看对象的生命周期是否出了该函数作用域之后会不会析构,析构就选择传值返回,不析构就选择传引用返回(减少拷贝构造)。

3.运算符重载&赋值重载

自定义类型无法通过编译器直接运算,所以搞出了一个运算符重载,增加了代码的可读性。

 运算符重载大概就是:返回值类型 operator操作符(参数);别把operator写错了qwq

但是不对劲的是,为什么这里会报错?那是因为我们给这个重载函数是外部函数,不是类的成员函数,所以说我们不能调用类封装的成员变量。那我们应该怎么办呢?C++一般使用友元函数或者直接把封装到类的成员函数里面,我们这里采取后者的方法。

Date.h
#include<iostream>
using namespace std;
//拷贝构造
//d1(d2)
// 
//赋值重载
//d1=d2
//
class Date
{
public:
	
	Date(int year = 1, int month = 1, int day = 1);
	void Print();
	//成员函数都有隐含的this指针
	bool operator==(const Date& d1);
private:
    int _year;
    int _month;
    int _day;
}
Date.cpp
bool Date::operator==(const Date& d1)
{
	return _year == d1._year
		&& _month == d1._month
		&& _day == d1._day;
}

赋值重载跟拷贝构造有着相似的地方,如果自己没有写赋值重载函数,编译器会自己生成一个赋值重载函数,但是对于只能深拷贝的代码,复制重载也是得自己写的,例如栈。这里给出自己想实现赋值重载函数的例子:

Date& operator=(const Date& d)
{
	if (this != &d)
	{
		this->_year = d._year;
	}
	return *this;
}

 前置++与后置++问题

那么前置和后置++的运算符重载函数该怎么写呢?operator++()这样就分辨不出来了,这时候老本可是犯了难,冥思苦想,逻辑闭环的方法真给他想到了——给后置++的参数硬塞一个int,operator++(int),这样就让前置与后置有了区别。

const 修饰的成员函数

这个const修饰成员函数是修饰函数里面的this指针指向的内容——const Date&this; 

4.手撕日期类

大致给一个日期类的代码,大家可以下去自己去尝试:

//Date.h
#pragma once
#include<iostream>
using namespace std;
class Date
{
public:
	Date(int year = 1, int month = 1, int day = 1);
	void Print() const;//成员函数都有this指针
	//const修饰this指针->const Date&const this
	int GetMonthDay(int year, int month)
	{
		int GetMonthDayArray[13] = { -1,31,28,31,30,31,30,31,31,30,31,30,31 };
		if (month == 2 && ((year % 4 == 0 && year % 100 != 0)
			|| (year % 400 == 0)
			)
			)
		{
			return 29;
		}
		else
		{
			return GetMonthDayArray[month];
		}
	}
	//bool CheckDate();

	bool operator<(const Date& d) const;
	bool operator<=(const Date& d) const;
	bool operator>(const Date& d) const;
	bool operator>=(const Date& d) const;
	bool operator==(const Date& d) const;
	bool operator!=(const Date& d) const;

	// d1 += 100
	Date& operator+=(int day);
	Date operator+(int day) const;

	// d1 -= 100
	//Date& operator-=(int day);

	// d1 - 100;
	//Date operator-(int day) const;

	// d1 - d2
	//int operator-(const Date& d) const;
private:
	int _year;
	int _month;
	int _day;
};

// 重载
//ostream& operator<<(ostream& out, const Date& d);
//istream& operator>>(istream& in, Date& d);
//Date.cpp
#include"C++7.h"
Date::Date(int year,int month,int day)
{
	_year = year;
	_month = month;
	_day = day;
	cout << "Date" << endl;
}

void Date::Print() const
{
	cout << _year << "-" << _month << "-" << _day << endl;
}

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

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

bool Date::operator==(const Date& d) const
{
	return _year == d._year 
		&& _month == d._month 
		&& _day == d._day;
}

bool Date::operator>=(const Date& d) const
{
	return *this > d || *this == d;
}

bool Date::operator<=(const Date& d) const
{
	return *this < d || *this == d;
}

bool Date::operator!=(const Date& d) const
{
	return !(*this == d);
}

// d1 += 100
Date& Date::operator+=(int day)
{
	_day += day;
	while (_day > GetMonthDay(_year, _month))
	{
		_day -= GetMonthDay(_year, _month);//调用opertor-=
		++_month;
		if (_month == 13)
		{
			++_year;
			_month = 1;
		}
	}
	return *this;
}

Date Date::operator+(int day) const
{
	Date tmp = *this;
	tmp += day;
	return tmp;
}

//d1 -= 100
//Date& Date::operator-=(int day)
//{
//
//}

// d1 - 100;
//Date Date::operator-(int day) const
//{
//
//}

// d1 - d2
//int Date::operator-(const Date& d) const
//{
//
//}
//test.cpp
#include"C++7.h"
int main()
{
	Date d1(2024, 9, 1);
	d1 += 5;//+=
	Date d2;
	d2 = d1 + 5;//+
	d1.Print();
	d2.Print();
}

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

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

相关文章

ACM第三次考核题解

ACM第三次考核题解 题目序号难度题目编号题目考察知识点1签到题A这是一道很难的题&#xff01;&#xff01;&#xff01;输出2迷之难度F神说要有光&#xff0c;于是有了手电筒贪心3简单BThis is a real English problem&#xff01;思维 英语4简单C玩具简单排序5简单I“近义词…

速通数据结构与算法第六站 树堆

系列文章目录 速通数据结构与算法系列 1 速通数据结构与算法第一站 复杂度 http://t.csdnimg.cn/sxEGF 2 速通数据结构与算法第二站 顺序表 http://t.csdnimg.cn/WVyDb 3 速通数据结构与算法第三站 单链表 http://t.csdnimg.cn/cDpcC 4 速通…

一文上手SpringSecurity【九】

在校验token的过滤器当中, 由于需要根据用户名称, 去查询出要认证的对象,然后再去数据库当中查询出角色列表、权限列表.频繁的操作数据库,可能会带来性能瓶颈, 那么我们该如何解决呢? 我们可以引入Redis, 将认证的对象,存储到Redis当中,在校验token的过滤器当中,可以直接从Red…

9.29 LeetCode 3304、3300、3301

思路&#xff1a; ⭐进行无限次操作&#xff0c;但是 k 的取值小于 500 &#xff0c;所以当 word 的长度大于 500 时就可以停止操作进行取值了 如果字符为 ‘z’ &#xff0c;单独处理使其变为 ‘a’ 得到得到操作后的新字符串&#xff0c;和原字符串拼接 class Solution { …

ServletContainerInitializer接口详解

版权声明 本文原创作者:谷哥的小弟作者博客地址:http://blog.csdn.net/lfdfhlServletContainerInitializer概述 ServletContainerInitializer是Servlet 3.0规范中引入的一个接口,它的主要目的是允许开发者在Servlet容器(如Tomcat、Jetty等)启动时执行一些自定义的初始化代…

synchronized相关知识

1、对象头Markword 2、锁升级过程 无锁 偏向锁&#xff1a;只有一个线程过来加锁&#xff0c;Markword对应变化&#xff1a;偏向线程ID存储当前线程ID&#xff0c;偏向锁标志位置成1&#xff0c;锁标志位置为01&#xff1b;此后如果当前线程再次获取锁&#xff0c;只需对比偏…

《十年国庆游,洞察中国旅游新趋势》

作者&#xff1a;侯炯 一、十年国庆旅游数据总览 过去十年&#xff0c;中国国庆旅游市场呈现出丰富的变化和强劲的发展态势。从接待游客人次来看&#xff0c;2014 年接待国内游客 4.75 亿人次&#xff0c;到 2019 年已增长至 7.82 亿人次&#xff0c;2023 年国内旅游出游人数更…

【预备理论知识——1】深度学习:概率论概述

简单地说&#xff0c;机器学习就是做出预测。 概率论 掷骰子 假设我们掷骰子&#xff0c;想知道看到1的几率有多大&#xff0c;而不是看到另一个数字。 如果骰子是公平的&#xff0c;那么所有六个结果{1,…, 6}都有相同的可能发生&#xff0c; 因此我们可以说 1 发生的概率为1…

【数据结构】图的最小生成树

快乐的流畅&#xff1a;个人主页 个人专栏&#xff1a;《C游记》《进击的C》《Linux迷航》 远方有一堆篝火&#xff0c;在为久候之人燃烧&#xff01; 文章目录 引言一、最小生成树的概念二、Kruskal算法2.1 思想2.2 实现 三、Prim算法3.1 思想3.2 实现 四、Kruskal和Prim的对比…

container_of 函数的分析

这个函数的目的是&#xff0c; 通过结构体里面的内容 找到 大结构体的 基地址。 函数的原型是&#xff1a;  &#xff30;&#xff34;&#xff32;是指针 &#xff54;&#xff59;&#xff50;&#xff45; &#xff0c; &#xff4d;&#xff45;&#xff4d;&#xff…

新手上路:Anaconda虚拟环境创建和配置以使用PyTorch和DGL

文章目录 前言步骤 1: 安装 Anaconda步骤 2: 创建新的 Anaconda 环境步骤 3: 安装最新版本的 PyTorch步骤 4: 安装特定版本的 PyTorch步骤 5: 安装最新版本的 DGL步骤 6: 安装特定版本的 DGL步骤 7: Pycharm中使用虚拟环境解释器第一种情况&#xff1a;创建新项目第二种情况&am…

Word办公自动化的一些方法

1.Word部分内容介绍 word本身是带有格式的一种文档&#xff0c;有人说它本质是XML&#xff0c;所以一定要充分利用标记了【样式】的特性来迅速调整【格式】&#xff0c;从而专心编辑文档内容本身。 样式&#xff08;集&#xff09; 编号&#xff08;多级关联样式编号&#xff…

Tomcat系列漏洞复现

CVE-2017-12615——Tomcat put⽅法任意⽂件写⼊漏洞 漏洞描述 当 Tomcat运⾏在Windows操作系统时&#xff0c;且启⽤了HTTP PUT请求⽅法&#xff08;例如&#xff0c;将 readonly初始化参数由默认值设置为false&#xff09;&#xff0c;攻击者将有可能可通过精⼼构造的攻击请求…

探索 Snowflake 与 Databend 的云原生数仓技术与应用实践 | Data Infra NO.21 回顾

上周六&#xff0c;第二十一期「Data Infra 研究社」在线上与大家相见。活动邀请到了西门子数据分析师陈砚林与 Databend 联合创始人王吟&#xff0c;为我们带来了一场关于 Snowflake 和 Databend 的技术探索。Snowflake&#xff0c;这个市值曾超过 700 亿美元的云原生数据仓库…

Android 安卓内存安全漏洞数量大幅下降的原因

谷歌决定使用内存安全的编程语言 Rust 向 Android 代码库中写入新代码&#xff0c;尽管旧代码&#xff08;用 C/C 编写&#xff09;没有被重写&#xff0c;但内存安全漏洞却大幅减少。 Android 代码库中每年发现的内存安全漏洞数量&#xff08;来源&#xff1a;谷歌&#xff09…

资质申请中常见的错误有哪些?

在申请建筑资质的过程中&#xff0c;企业可能会犯一些常见的错误&#xff0c;以下是一些需要避免的错误&#xff1a; 1. 资料准备不充分&#xff1a; 申请资质需要提交大量的资料&#xff0c;包括企业法人资料、财务报表、业绩证明等。资料不齐全或不准确都可能导致申请失败。…

汽车线束之故障诊断方案-TDR测试

当前&#xff0c;在汽车布局中的线束的性能要求越来越高。无法通过简单的通断测试就能满足性能传输要求。早起对智能化要求不高&#xff0c;比如没有激动雷达、高清摄像、中央CPU等。 近几年的智能驾驶对网络传输要求越来越高&#xff0c;不但是高速率&#xff0c;还需要高稳定…

【C++题目】7.双指针_和为 s 的两个数字

文章目录 题目链接&#xff1a;题目描述&#xff1a;解法C 算法代码&#xff1a;图解 题目链接&#xff1a; LCR 179.查找总价格为目标值的两个商品 题目描述&#xff1a; 解法 解法一&#xff08;暴力解法&#xff0c;会超时&#xff09; 两层 for 循环列出所有两个数字的组合…

一种使用 SUMO + Python 联合仿真平台

一种使用 SUMO Python 联合仿真平台&#xff08;一&#xff09; 本文适用人群包括但不仅限于【交通运输】【车辆工程】【自动化控制】【计算机科学与技术】等专业本科生、研究生、博士生。本文通过在Pycharm平台&#xff0c;使用Python语言 Traci工具包&#xff0c;调用SUMO客…

【步联科技身份证】 身份证读取与解析———未来之窗行业应用跨平台架构

一、身份证解析代码 C# function 身份证数据解析_湖南步联科技(wzxx) {var result {};result[xm] wzxx.substr(0, 15);result[xbdm] wzxx.substr(15, 1);result[mzdm] wzxx.substr(16, 2);result[csrq] wzxx.substr(18, 8);result[dzmc] wzxx.substr(26, 35);result[gms…