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

类和对象(中)

类的六个默认成员函数

如果一个类中一个默认成员函数也没有那这个类我们叫作空类。
但是如果一个类中每有默认成员函数的话,会怎样呢?答案是编译器会帮我们自动实现类。
在这里插入图片描述

拷贝构造

构造函数是一个特殊的成员函数,函数名和类名相同没有返回值。创建类类型对象时,由编译器自动调用。并且在对象整个生命空间周期类只调用一次。

构造函数作用在于初始化对象类似于int a=1;给啊初始化为1;
我们看一下具体的代码片段:

//重点关注注释部分
//代码是我做题通过后进行拷贝下来的代码,可以适当理解一下,题目最后放在末尾
class date {
public:date(int year, int month, int day , int days) //构造函数,没有返回值,但是不需要void{_year = year;_month = month;_day = day;_days = days;} date(int year = 2025, int month = 4 , int day =23 , int days = 100) //函数重载《也是无参构造函数,无参构造函数一个类中只能存在一个》{_year = year;_month = month;_day = day;_days = days;} int Get_month(int month){int arr_month[13] = { 0,31,28,31,30,31,30,31,31,30,31,30,31 };if (month==2 && _year % 4 == 0 && _year % 100 != 0 || _year % 400 == 0){arr_month[2] = 29;}return arr_month[month];}date datecount(){int i = Get_month(_month);_days += _day;while (_days > i){_month++;if (_month > 12){_year++;_month = 1;}_days -= i;i= Get_month(_month);}_day = _days;return *this;}void Print(){//打印年cout << _year << "-";//打印月份if (_month < 10){cout << 0 << _month << "-";}elsecout << _month << "-";//打印日if (_day < 10){cout << 0 << _day << endl;}elsecout << _day << endl;}private:int _year;int _month;int _day;int _days;
};int main()
{int n;cin >> n;while (n--){int year, month, day;int days;cin >> year >> month >> day >> days;date a(year, month, day, days); //编译器自动调用构造函数,用来初始化对象。a.datecount().Print();//日期打印}return 0;
}

还有一点是,构造函数跟其他成员函数一样可支持重载

你可能会问,如果我没有写构造函数会怎样?
这个时候编译器就会有自己的想法,编译器会自己生成一个无参的构造函数,并进行调用。但是这有时候我们并不知道编译器构造的成员函数是怎样的,不知道是否能正确的完成初始。所以在C++11中打了一个补丁。即在内置类型成员变量在类中声明时可以给默认值

private:int _year =  2025;  //这时声明不是初始化int _month = 4;		//这时声明不是初始化int _day = 23;		//这时声明不是初始化int _days = 24;		//这时声明不是初始化

析构函数

析构函数也是一个特殊的成员函数,函数名和类名前加一个 ~ 符号,同样没有返回值,也不需要写 void
它的作用是:在对象生命周期结束时自动调用,用来进行清理工作,比如释放内存、关闭文件、断开网络连接等。

基本格式:

~类名()
{// 清理操作
}

对于这段日期代码来说,我们的类中没有使用 new 动态分配内存,因此不写析构函数也没关系,编译器会默认生成一个“空析构函数”。

但出于规范,我们可以手动写一个出来作为示例:

class date {
public:// 构造函数略~date(){// 目前这个类没有资源需要手动释放// 这里只是说明析构函数的位置cout << "析构函数被调用,日期对象被销毁" << endl;}// 其他成员函数略private:int _year;int _month;int _day;int _days;
};

注意事项:

  • 析构函数不能有参数、不能被重载
  • 如果类中有用 new 申请了堆空间(如 int* p = new int),必须写析构函数释放资源,否则会内存泄漏。
  • 析构函数通常不需要手动调用,在对象生命周期结束时自动调用

示例输出位置:

main() 函数中执行完这一行:

date a(year, month, day, days);

对象 a 在这个作用域结束时就会被销毁,自动调用析构函数。为了验证我们可以加入一段测试:

int main()
{{date a(2025, 4, 23, 100);a.datecount().Print();} // 在这个大括号结束的位置,a 被销毁,会调用析构函数return 0;
}

运行时会输出:

2025-08-01
析构函数被调用,日期对象被销毁

小结

函数特点何时调用
构造函数用于初始化对象创建对象时
析构函数用于清理资源销毁对象时

你可以简单记住它们是“出生与销毁”这一对搭档。

拷贝构造函数

拷贝构造函数用于创建一个新对象,并用一个已有对象进行初始化。

格式:

date(const date& d)
{_year = d._year;_month = d._month;_day = d._day;_days = d._days;cout << "调用拷贝构造函数" << endl;
}

特点:

  • 参数是一个同类对象的引用,并且通常加上 const
  • 如果不写,编译器会默认生成一个“浅拷贝”的拷贝构造函数。

示例:

date d1(2025, 4, 23, 100);
date d2 = d1; // 调用拷贝构造函数

当我们传值或返回对象时,也可能调用拷贝构造:

date foo(date d) // 这里传值会调用拷贝构造
{return d;    // 返回也可能触发拷贝
}

赋值运算符重载

用于对象赋值,即:一个已经存在的对象被另一个对象赋值。

格式:

date& operator=(const date& d)
{if (this != &d){_year = d._year;_month = d._month;_day = d._day;_days = d._days;}cout << "调用赋值运算符重载" << endl;return *this;
}

注意:

  • 需要返回 *this 的引用,以支持链式赋值 a = b = c;
  • 自赋值检查很重要:if (this != &d)
  • 如果类中有资源分配(如 new),一定要手动写赋值运算符重载,避免浅拷贝问题。

const 成员函数

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

特点:

  • 在函数后加 const 表示这个函数不会修改对象的成员变量
  • 只能调用其他 const 成员函数。
  • 常用于 const 对象,如:
const date d(2025, 4, 23, 100);
d.Print(); // 只能调用 const 函数

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

普通取地址:

date* operator&()
{cout << "调用取地址操作符&" << endl;return this;
}

const 取地址:

const date* operator&() const
{cout << "调用 const 取地址操作符&" << endl;return this;
}

这两个可以帮助我们在调试或做特殊封装时了解对象的地址行为。


日期打印

http://www.xdnf.cn/news/108595.html

相关文章:

  • Spring AI 会话记忆(笔记)
  • 【3.2】pod详解—— Pod的相位(phase)状态(status)
  • Linux常用指令
  • 小刚说C语言刷题——1338求圆环的面积
  • C++二分法详解
  • el-table 目录树列表本地实现模糊查询
  • Linux部署Redis主从
  • 天梯-零头就抹了吧
  • 实操Obsidian+Ollama+deepseek构建本地知识库
  • C语言五子棋项目
  • [计算机科学#1]:计算机的前世今生,从算盘到IBM的演变之路
  • flex布局说明
  • 百万点数组下memset、memcpy与for循环效率对比及原理分析
  • 经典算法 小数点后的第n位
  • 语音合成之四基于LLM的语音合成
  • Sql刷题日志(day5)
  • JVM理解(通俗易懂)
  • 2025年渗透测试面试题总结-拷打题库14(题目+回答)
  • 时间自动填写——电子表格公式的遗憾(DeepSeek)
  • A13 自定义系统服务使用总结
  • Kafka集群
  • ABP-Book Store Application中文讲解 - Part 0:开发环境搭建
  • 意见反馈留言二维码制作
  • leetcode-枚举
  • Langchain coercion简介
  • deeplab语义分割训练自定数据集
  • leve1.4
  • LLama Factory从入门到放弃
  • iThenticate英文查重系统怎么用?
  • 【AI论文】在非政策指导下学习推理