好的继上期,我们今天带来c++类与对象系列的继续学习。
类的6个默认成员函数
六个默认成员函数会实现6个功能,我们先来看第一个:
构造函数
上一段代码:
#define _CRT_SECURE_NO_WARNINGS 1
#include<iostream>
using namespace std;
class Date
{
public:
void Init(int year, int month, int day)
{
_year = year;
_month = month;
_day = day;
}
void Printf()
{
cout << _year << '/' << _month << '/' << _day << endl;
}
private:
int _year;
int _month;
int _day;
};
int main()
{
Date d1;
d1.Printf();
return 0;
}
大家在刚开始写代码的时候,比如说这里写了一个date类,我们忘记了初始化,直接调用printf函数,由于没有初始化,三个变量的值就会使三个随机数:
这是不是就麻烦了,这个事情不仅仅是我们经常忘记,c++祖师爷也经常忘记,所以祖师爷就想给c++多个功能,自己初始化,所以祖师爷就搞了一个新的东西:构造函数
构造函数的特性:
#define _CRT_SECURE_NO_WARNINGS 1
#include<iostream>
using namespace std;
class Date
{
public:
//构造函数
Date()
{
_year = 2023;
_month = 8;
_day = 30;
cout << "构造函数" << endl;
}
void Printf()
{
cout << _year << '/' << _month << '/' << _day << endl;
}
private:
int _year;
int _month;
int _day;
};
int main()
{
Date d1;
d1.Printf();
return 0;
}
#define _CRT_SECURE_NO_WARNINGS 1
#include<iostream>
using namespace std;
class Date
{
public:
//构造函数
Date()
{
_year = 2023;
_month = 8;
_day = 30;
cout << "构造函数" << endl;
}
//有参构造函数
Date(int year,int month,int day)
{
_year = year;
_month = month;
_day = day;
cout << "有参构造函数" << endl;
}
void Printf()
{
cout << _year << '/' << _month << '/' << _day << endl;
}
private:
int _year;
int _month;
int _day;
};
int main()
{
Date d1;
d1.Printf();
Date d2(2023,1,1);
d2.Printf();
return 0;
}
#define _CRT_SECURE_NO_WARNINGS 1
#include<iostream>
using namespace std;
class Date
{
public:
Date(int year=2023,int month=8,int day=30)
{
_year = year;
_month = month;
_day = day;
cout << "有参构造函数" << endl;
}
void Printf()
{
cout << _year << '/' << _month << '/' << _day << endl;
}
private:
int _year;
int _month;
int _day;
};
int main()
{
Date d1;
d1.Printf();
Date d2(2023,1,1);
d2.Printf();
return 0;
}
这样不单单就简介了,还更灵活了,看不懂的同学自觉去看前两期内容
两次都是调用的这个构造函数,这就是缺省的魅力
#define _CRT_SECURE_NO_WARNINGS 1
#include<iostream>
using namespace std;
class Date
{
public:
Date(int year=2023,int month=8,int day=30)
{
_year = year;
_month = month;
_day = day;
cout << "有参构造函数" << endl;
}
void Printf()
{
cout << _year << '/' << _month << '/' << _day << endl;
}
private:
int _year;
int _month;
int _day;
};
int main()
{
Date d1;
d1.Printf();
Date d2(2023,1,1);
d2.Printf();
Date d3(2023);
d3.Printf();
Date d4(2023, 12);
d4.Printf();
return 0;
}
好好好,缺省参数被我们玩坏了
class Stack
{
public:
Stack()
{
a = nullptr;
top = capacity = 0;
}
void Push(int x)
{
if (top == capacity)
{
cout << capacity << "扩容" << endl;
size_t newcapacity = capacity == 0 ? 4:capacity * 2;
a = (int*)realloc(a, sizeof(int) * newcapacity);
capacity = newcapacity;
}
a[top++] = x;
}
private:
int *a;
int top;
int capacity;
int size;
};
1、我们不写才会生成,我们写了就不会生成了
2、内置类型的成员不会处理
析构函数
析构函数的特性
析构函数是特殊的成员函数,其特征如下:
1. 析构函数名是在类名前加上字符 ~。
2. 无参数无返回值类型。
3. 一个类只能有一个析构函数。若未显式定义,系统会自动生成默认的析构函数。注意:析构 函数不能重载
4. 对象生命周期结束时,C++编译系统系统自动调用析构函数
#define _CRT_SECURE_NO_WARNINGS 1
#include<iostream>
using namespace std;
class Date
{
public:
Date(int year = 2023, int month = 8, int day = 30)
{
_year = year;
_month = month;
_day = day;
cout << "有参构造函数" << endl;
}
void Printf()
{
cout << _year << '/' << _month << '/' << _day << endl;
}
~Date()
{
cout << "析构函数" << endl;
}
private:
int _year;
int _month;
int _day;
};
int main()
{
Date d1;
d1.Printf();
Date d2(2023, 1, 1);
d2.Printf();
return 0;
}
看,我们写的析构函数自动被调用了
日期类的析构函数我们看不出什么来,来试试栈的析构函数
#define _CRT_SECURE_NO_WARNINGS 1
#include<iostream>
using namespace std;
class Stack
{
public:
Stack()
{
cout << "构造函数" << endl;
a = nullptr;
top = capacity = 0;
}
void Push(int x)
{
if (top == capacity)
{
cout << capacity << "扩容" << endl;
size_t newcapacity = capacity == 0 ? 4 : capacity * 2;
a = (int*)realloc(a, sizeof(int) * newcapacity);
capacity = newcapacity;
}
a[top++] = x;
}
~Stack()
{
cout << "析构函数" << endl;
free(a);
a = nullptr;
top = capacity = 0;
}
private:
int* a;
int top;
int capacity;
int size;
};
int main()
{
Stack s1;
return 0;
}
自动调用,无论写多少个,所以这就生下了我们很多初始化和删除的时间
拷贝构造函数
上代码:
#include<iostream>
using namespace std
class Date
{
public:
Date(int year = 1900, int month = 1, int day = 1)
{
_year = year;
_month = month;
_day = day;
}
// Date(const Date& d) // 正确写法
Date(const Date& d) // 错误写法:编译报错,会引发无穷递归
{
_year = d._year;
_month = d._month;
_day = d._day;
}
private:
int _year;
int _month;
int _day;
};
int main()
{
Date d1;
Date d2(d1);
return 0;
}
直接拷贝的d1给d2赋值
拷贝构造的特征:
赋值运算符重载
上代码:
#define _CRT_SECURE_NO_WARNINGS 1
#define _CRT_SECURE_NO_WARNINGS 1
#include<iostream>
using namespace std;
class Date
{
public:
Date(int year = 2023, int month = 8, int day = 30)
{
_year = year;
_month = month;
_day = day;
cout << "有参构造函数" << endl;
}
void Printf()
{
cout << _year << '/' << _month << '/' << _day << endl;
}
~Date()
{
cout << "析构函数" << endl;
}
private:
int _year;
int _month;
int _day;
};
int main()
{
Date d1(2023, 1, 1);
Date d2(2023, 1, 2);
d1 < d2;
return 0;
}
大家看看这样比较两个日期类的变量行不行
答案是当然不行
但是这样写
int i,j;
i<j;
这样比较,就可以,这是因为编译器知道int变量的存储模式和比较方式
那么我们可不可以让编译器也可以直接比较date
这就涉及到这个课题内容运算符重载
#define _CRT_SECURE_NO_WARNINGS 1
#define _CRT_SECURE_NO_WARNINGS 1
#include<iostream>
using namespace std;
class Date
{
public:
Date(int year = 2023, int month = 8, int day = 30)
{
_year = year;
_month = month;
_day = day;
cout << "有参构造函数" << endl;
}
void Printf()
{
cout << _year << '/' << _month << '/' << _day << endl;
}
~Date()
{
cout << "析构函数" << endl;
}
//private:
int _year;
int _month;
int _day;
};
bool operator<(const Date& x1, const Date& x2)
{
if (x1._year < x2._year)
{
return true;
}
else if (x1._year == x2._year && x1._month < x2._month)
{
return true;
}
else if (x1._year == x2._year && x1._month == x2._month && x1._day < x2._day)
{
return true;
}
else
{
return false;
}
}
int main()
{
Date d1(2023, 1, 1);
Date d2(2023, 1, 2);
cout<<(d1 < d2)<<endl;
return 0;
}
有函数重载,就有运算符重载,上边就是使用规则,大家记住就行了
那有<运算符,就有<=,>,>=,=,+,-,+=,-=
博主在这里一一实现了
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;
}
bool operator<(const Date& d)
{
if (_year < d._year)
{
return true;
}
else if (_year == d._year && _month < d._month)
{
return true;
}
else if (_year == d._year && _month == d._month && _day < d._day)
{
return true;
}
else
{
return false;
}
}
bool operator==(const Date& d)
{
return _year == d._year
&& _month == d._month
&& _day == d._day;
}
// d1 <= d2
bool operator<=(const Date& d)
{
return *this < d || *this == d;
}
bool operator>(const Date& d)
{
return !(*this <= d);
}
bool operator>=(const Date& d)
{
return !(*this < d);
}
bool operator!=(const Date& d)
{
return !(*this == d);
}
int GetMonthDay(int year, int month)
{
int monthArray[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)))
{
return 29;
}
return monthArray[month];
}
Date& operator+=(int day)
{
_day += day;
while (_day > GetMonthDay(_year, _month))
{
// 月进位
_day -= GetMonthDay(_year, _month);
++_month;
// 月满了
if (_month == 13)
{
++_year;
_month = 1;
}
}
return *this;
}
Date operator+(int day)
{
Date tmp(*this);
tmp += day;
return tmp;
//tmp._day += day;
//while (tmp._day > GetMonthDay(tmp._year, tmp._month))
//{
// // 月进位
// tmp._day -= GetMonthDay(tmp._year, tmp._month);
// ++_month;
// // 月满了
// if (tmp._month == 13)
// {
// ++tmp._year;
// tmp._month = 1;
// }
//}
//return tmp;
}
private:
// 内置类型
int _year;
int _month;
int _day;
};
关于日期各种加减乘除运算的逻辑实现是没有任何难度的,就是年完月,月完日,进位加
大家要理解的是重载的操作文章来源:https://www.toymoban.com/news/detail-679904.html
好的类和对象的中篇就到这里,对于默认成岩函数基本就接好玩了,期待三连文章来源地址https://www.toymoban.com/news/detail-679904.html
到了这里,关于重生c++系列之类与对象(中篇)的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!