定义一个日期类

#include <iostream>
#include <assert.h>
using namespace std;class Date
{
public:void Display();
private:int _year;int _month;int _day;
};

注意:

在定义一个类的时候往往会将其成员变量定义为私有,成员函数定义为公有.这是为了达到软件工程上的高内聚低耦合的要求

this指针

每一个函数都有自己的形式指针,它的名字是固定的,称为this,同时this指针是隐式的.
编译器会对成员函数进行优化,在对象调用成员函数的时候,此时会将该对象的地址传递给成员函数的第一个参数
同时this指针是成员函数隐含指针参数,我们程序员不能自己将其加到成员函数的形式参数列表中,也不能在调用的时候显示的将对象的地址传给this指针

注意:

this指针是形式参数,既然是形式参数那么它就会在栈上,但是在Linux下,this指针是被存放在寄存器中.同时谁来调用this成员函数那么this指针就指向谁

构造函数

构造函数可以达到原子性,即对象被定义的时候就会被初始化.在定义类的时候我们呢看到通常会将成员函数定义为私有但是私有成员变量在类外是不能被访问的.为了对成员函数进行初始化,此时就需要构造函数来对私有成员变量进行初始化.同时构造函数只在对象被定义的时候仅仅被执行一次.下面来说一下构造函数的特点
1.函数名和类名相同
2.无返回值
3.对象构造时系统自己调用对应的构造函数
4.构造函数可以重载(函数名相同, 参数不同)
5.构造函数可以在类里面定义也可以在类外面定义
6.如果类中没有定义一个构造函数,系统会默认生成一个缺省的构造函数,但是当我们定义了构造函数,此时系统就不会生成默认的缺省构造函数,而会定义我们自己定义的构造函数,编译器在对其进行初始化的时候,内置的类型会被初始化,但是自定义的不会进行初始化
7.无参的构造函数和全缺的构造函数都认为是缺省构造函数.并且缺省的构造函数只能有一个

几种构造函数

class Date
{
public:// 1.无参的构造函数// Date()// {// }// 2.缺省构造函数Date(int year = 1900, int month = 1, int day = 1){if(year < 1900 || month < 0 || month > 12 || day < 0 || day > 31){assert(0);}_year = year;_month = month;_day = day;}//3. 带参的构造函数// Date (int year, int month, int day)// {//     _year = year;//     _month = month;//     _day = day;// }// 4. 拷贝构造函数,创建一个对象Date(Date& d){_year = d._year;_month = d._month;_day = d._day;}void Display();
private:int _year;int _month;int _day;
};

注意:

拷贝构造其实就可以理解为一种特殊的构造函数,它是构造函数的重载,同时注意拷贝构造是对象的创建,而我们后面将所说的赋值是两个对象都已经存在
同时拷贝构造必须传引用,因为如果传值的话那么就会出现无穷递归(拷贝构造就要传参,传参就要拷贝构造)
3.如果自己没有显示进行定义,那么系统就会自己生成默认缺省构造函数.缺省的时候拷贝构造函数就会依次拷贝类成员进行初始化

析构函数

1.和类的名字前面加上一个~
2.无返回值
3.一个类有且只有一个析构函数(因为没有参数,不能构成重载),如果我们自己不写编译器会自动生成
4.对象生命周期结束的时候,系统调用析构函数
5.析构函数不能删除对象,只是对对象进行清理

注意:

如果需要清理成员变量(动态开辟空间),则自己写析构函数,对象在定义的时候一定调用了构造,生命周期结束的时候就一定调用了析构函数

运算符重载

Date& operator = (const Date& d){this -> _year = d._year;this -> _month = d._month;this -> _day = d._day;return *this;}// d2 == d3// d2.operator(*this, d3)bool operator == (const Date& d) {if(this -> _year == d._year && this -> _month == d._month && this -> _day == _day){return true;}return false;}bool operator != (const Date d){if(!(*this == d)){return true;}return false;}//d1 > d2//d1.operator > (this, d2)bool operator > (const Date& d) {if(this -> _year > d._year){return true;}if(this -> _year == d._year){if(this -> _month > d._month){return true;}}if(this -> _month == d._month){if(this -> _day > d._day){return true;}}return false;}//d2 < d3//d2.operator(this, d3)bool operator < (const Date& d) {if(*this == d || *this > d){return false;}return true;}// d2 >= d3bool operator >= (const Date& d){if(*this > d || *this == d){return true;}return false;}//d2 <= d3bool operator <= (const Date& d){if(*this < d || *this == d){return true;}return false;}//d2++Date& operator ++ () // 前置 {++( this -> _day );if(this -> _day > GetMonthDay(this -> _year, this -> _month)){this -> _day = 1;++(this -> _month);if((this -> _month) > 12){++(this -> _year);this -> _month = 1;}}return *this;}//d2++Date operator ++ (int) // 后置 {Date ret = (*this);++( *this );return ret;}//2018-1-1Date& operator -- (){--(this -> _day);if(this -> _day == 0){(this -> _month)--;if(this -> _month == 0){this -> _year -= 1;this -> _month = 12;}(this -> _day) += GetMonthDay(this -> _year, this -> _month);}return *this;}Date operator -- (int)//后置{Date ret = *this;--(*this);return ret;}Date& operator += (int day){this -> _day = this -> _day + day;while(this -> _day > GetMonthDay(this -> _year, this -> _month)){this -> _day = this -> _day - GetMonthDay(this -> _year, this -> _month);this -> _month ++;if(this -> _month > 12){this -> _month = 1;this -> _year ++;}}return *this;}//d1 + 30//d1.operator(this, day)Date operator + (int day) {Date ret = *this;ret += day;return ret;}Date& operator -= (int day){this -> _day -= day;while(this -> _day <= 0){this -> _month --;if(this -> _month < 1){this -> _month = 12;this -> _year --;}this -> _day += GetMonthDay(this -> _year, this -> _month);}return *this;}Date operator - (int day){Date ret = *this;ret -= day;return ret;}// 2018-1-31  -  2018-1-1// d1.operator(this, d2)int operator - (const Date& d){int count = 0;//记录天数while(*this > d){--(*this);( *this ).Display();++count;}return count;}void Display()//展示日期类{cout<<_year<<"-"<<_month<<"-"<<_day<<endl;}int GetMonthDay(int year, int month){int day[13] = {0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};if(( year %4 == 0 && year % 100 != 0 ) || ( year % 400 == 0 )){day[month] = day[2] + 1;}return day[month];}

输入探索构造函数

类的成员函数有两种初始化方式
1.初始化列表
以一个冒号开始, 接着一个逗号分隔数据列表, 每个数据成员都在括号里进行初始化. 尽量使用初始化列表, 因为初始化列表更加高效.
2.构造函数体内进行赋值

初始化列表为什么更加高效
1.初始化列表不写, 编译器会自动走一次(自定义成员变量)
2.初始化列表可以认为是成员变量定义的地方
3.构造函数体内赋值会产生临时变量, 但是初始化列表不会产生临时变量

那些成员变量必须放在初始化列表中

1.常量成员变量(常量创建时必须初始化)
2.引用类型成员变量(引用成员变量创建时必须初始化)
3.没有缺省构造函数的自定义类型
4.成员变量初始化的时候按照声明顺序依次初始化,而非初始化列表出现的顺序

3_V1-类和对象 -- 默认成员函数相关推荐

  1. 浅谈C++类中的默认成员函数

    概述 在C++中,类与C语言中的结构体类似,类与结构体的不同之处便是在其内部多了几个成员函数还有几个访问限定符,访问限定符有public(公共).protected(保护).private(私有),而 ...

  2. PythonC++相互混合调用编程全面实战-16c++调用python的类实例化对象访问成员函数和成员

    作者:虚坏叔叔 博客:https://xuhss.com 早餐店不会开到晚上,想吃的人早就来了!

  3. 一文带你入门C++,类与对象、6个默认成员函数、this指针以及static关键字。

    C++98关键字:63个 一.命名空间规则(namespace) 1.命名空间可以解决函数.全局变量名重复的问题,包在不同的命名空间里的重复函数,实际就是两个完全无关的函数. 2.命名空间允许续嵌套: ...

  4. 【C++从入门到踹门】第三篇:类和对象(中)类的默认成员函数

    目录 1.类的默认成员函数 2.构造函数 2.1 构造函数引入 2.2 构造函数概念及特点 3. 析构函数 3.1 析构函数引入 3.2 析构函数的概念 3.3 在哪些情况下会程序会执行析构函数? 3 ...

  5. 【C++】类和对象【中篇】--C++六个默认成员函数以及const成员函数

    文章目录 一.类的6个默认成员函数 二.构造函数 1.概念 2.特性 2.1特征分析--自动生成 2.2.特征分析--选择处理 2.3特征分析--默认构造 3.C++11补丁--缺省值 三.析构函数 ...

  6. C++类与对象(类中的六大默认成员函数)

    文章目录 类的默认成员函数 构造函数 概念 特征 自己定义构造函数 类中编写 传参方法 编译器自动生成的构造函数 定义变量方式 初始化规则 析构函数 概念 特性 自己定义析构函数 编译器自动生成的析构 ...

  7. 【 C++ 】类和对象(中)—— 类的6个默认成员函数

    目录 1.类的6个默认成员函数 2.构造函数 构造函数概念 构造函数特性 3.析构函数 析构函数概念 析构函数特性 4.拷贝构造函数 拷贝构造函数概念 拷贝构造函数特性 5.赋值运算符重载 运算符重载 ...

  8. 类与对象:类的6个默认成员函数: 构造函数、析构函数、拷贝构造函数、赋值操作符重载、默认拷贝构造与赋值运算符重载的问题、const成员函数、 取地址及const取地址操作符重载

    1.类的6个默认成员函数 如果一个类中什么成员都没有,简称为空类.任何一个类在我们不写的情况下,都会自动生成下面6个默认成员函数. 构造函数 析构函数 拷贝构造函数 赋值操作符重载 const成员函数 ...

  9. 【C++学习】类和对象(中)一招带你彻底了解六大默认成员函数

    前言:在之前,我们对类和对象的上篇进行了讲解,今天我们我将给大家带来的是类和对象中篇的学习,继续深入探讨[C++]中类和对象的相关知识!!! 目录 1. 类的6个默认成员函数 2. 构造函数 2.1概 ...

最新文章

  1. 【Linux】一步一步学Linux——wall命令(237)
  2. raspberry pi_如何将Raspberry Pi配置为微控制器
  3. 苹果M1芯片:如何开启一个时代
  4. 达梦数据库连接工具简介
  5. OpenCV各个版本的下载地址
  6. 15_岭回归-Ridge、岭回归API、线性回归和岭回归的对别;逻辑回归、sigmoid函数、逻辑回归公式、损失函数、逻辑回归API、逻辑回归案例、逻辑回归的优缺点、逻辑回归 VS 线性回归等
  7. 3D设计软件中怎么快速建模?浩辰3D快速建模教程
  8. 图片去水印软件分享!这三个好用的软件不能错过!​
  9. 数值计算之 最小二乘法(1)最小二乘计算与线性方程
  10. gmap mysql cachet,MySQL的缓存(Query Cache)
  11. 协同过滤推荐之基于近邻协同过滤(一)
  12. WebShell --冰蝎
  13. 调用麦克风列阵进行录音
  14. 【编译原理】分析PL0编译器
  15. 第二十次ScrumMeeting博客
  16. PhotoshopCS6-艺术照片处理技法精粹-05-除斑驳纹效果
  17. CSDN实训 - 通过Java修改游戏存档
  18. 《Reinforcement Learning: An Introduction》 读书笔记 - 目录
  19. 面试题1 -- Java 中,怎么在格式化的日期中显示时区?
  20. 使用MATLAB 将EASE-Grid 2.0投影坐标系下 的NC文件转换为相同坐标系下的geotiff文件

热门文章

  1. 分解质因数-洛谷P3200 [HNOI2009]有趣的数列
  2. SOJ 2800_三角形
  3. 介绍“Razor”— ASP.NET的一个新视图引擎
  4. kinect在openni下也能玩抠出人物换背景
  5. 基于混沌的图像置乱加密算法及matlab的实现,基于混沌的图像置乱加密算法及MATLAB的实现...
  6. 计算机原理及应用课程,课程介绍
  7. linux usleep 线程控制权_linux多线程同步—信号量
  8. as3 访问远程计算机,本地swf不能访问网络的解决办法
  9. 计算机二级高级应用考题,2016计算机二级MSOFFICE高级应用考试真题
  10. java底层 文件操作_JAVA的文件操作【转】