目录
1.介绍
2. 构造函数
1.特性
2.默认构造函数
3.析构函数
4.拷贝构造
5.赋值运算符重载
1. 运算符重载
2 .赋值运算符重载
1.介绍
任何一个类,在我们不写的情况下,都会生成默认的六个成员函数
2. 构造函数
1.特性
构造函数
是一个
特殊的成员函数,名字与类名相同
,
创建类类型对象时由编译器自动调用
,保证每个数据成员都有 一个合适的初始值,并且在对象的生命周期内只调用一次
。
构造函数
是特殊的成员函数,需要注意的是,构造函数的虽然名称叫构造,但是需要注意的是构造函数的主要任务并不是开空间创建对象,而是初始化对象
。
其特征如下:
1.
函数名与类名相同。
2.
无返回值。
3.
对象实例化时编译器
自动调用
对应的构造函数。
4.
构造函数可以重载。
1.特性 构造函数 是一个 特殊的成员函数,名字与类名相同 , 创建类类型对象时由编译器自动调用 ,保证每个数据成员都有 一个合适的初始值,并且在对象的生命周期内只调用一次 。 构造函数 是特殊的成员函数,需要注意的是,构造函数的虽然名称叫构造,但是需要注意的是构造函数的主要任务并不是开空间创建对象,而是初始化对象 。 其特征如下: 1. 函数名与类名相同。 2. 无返回值。 3. 对象实例化时编译器 自动调用 对应的构造函数。 4. 构造函数可以重载。
举例:
class Date
{
public:
Date()//无参构造
{
cout << "Date" << endl;
}
Date(int year, int month, int day)//有参构造
{
_year = year;
_month = month;
_day = day;
cout << "Date(int year, int month, int day)" << endl;
cout << _year << "-" << _month << "-" << _day << endl;
}
private:
int _year;
int _month;
int _day;
};
int main()
{
Date d1;//调用无参构造,后面无需加括号,防止与函数声明发生歧义
Date d2(2022, 5, 2);//调用有参构造
return 0;
}
会去调用构造函数
2.默认构造函数
如果类中没有显式定义构造函数,则C++编译器会自动生成一个无参的默认构造函数,一旦用户显式定义编译器将不再生成 无参的构造函数和全缺省的构造函数,以及我们未写编译器默认生成的构造函数,都称为默认构造函数,并且默认构造函数只能有一个。 在看以下代码:为何打印的是随机值呢?不是会自动调用默认构造函数吗?
原因:
C++把类型分成内置类型(基本类型)和自定义类型。内置类型就是语法已经定义好的类型:如 int/char,char*...,自定义类型就是我们使用class/struct/union自己定义的类型。 默认生成的构造函数对于内置类型的变量不做处理,对于自定义类型的变量才做处理 在看下面的代码:class A
{
public:
A(int a=10)
{
_a = a;
cout << _a << endl;
}
private:
int _a;
};
class Date
{
public:
void Print()
{
cout << _year << "年" << _month << "月" << _day << "日" << endl;
}
private:
int _year;//这三个变量不做处理
int _month;
int _day;
A a;//会调用它自己的默认构造函数处理
};
int main()
{
Date d1;//调用编译器自动生成的默认构造函数
d1.Print();
return 0;
}
结果:
10
-858993460年-858993460月-858993460日
C:Users10269DesktopcodeIF5.17Project1x64DebugProject1.exe (进程 15192)已退出,代码为 0。
按任意键关闭此窗口. . .
3.析构函数
概念:析构函数:与构造函数功能相反,析构函数不是完成对象的销毁,局部对象销毁工作是由 编译器完成的。而对象在销毁时会自动调用析构函数,完成类的一些资源清理工作
特性:
1. 析构函数名是在类名前加上字符 ~ 。 2. 无参数无返回值。 3. 一个类有且只有一个析构函数。若未显式定义,系统会自动生成默认的析构函数。 4. 对象生命周期结束时, C++ 编译系统系统自动调用析构函数。 举例:箭头位置按F11进去
生命周期结束时,会自动调用。
注意:若未显式定义,系统会自动生成默认的析构函数。并且,它与构造函数类似,对于自定义变量,默认的析构函数不做处理,自定义的变量,才会调用默认析构函数。(在未显示定义时)
4.拷贝构造 特征: 1. 拷贝构造函数 是构造函数的一个重载形式 。 2. 拷贝构造函数的 参数只有一个 且 必须使用引用传参 ,使用 传值方式会引发无穷递归调用 举例:
注意:若未显式定义,系统会自动生成默认的拷贝函数。默认的拷贝构造函数对象按内存存储按字节序完成拷 ,对于内置类型变量,默认的拷贝构造函数完成值拷贝(浅拷贝),自定义的变量,会去调用这个变量的拷贝构造。
拷贝构造函数的参数也可用用指针,但不建议这样做
5.赋值运算符重载
1. 运算符重载
介绍:
C++为了增强代码的可读性引入了运算符重载,运算符重载是具有特殊函数名的函数,也具有其返回值类 型,函数名字以及参数列表,其返回值类型与参数列表与普通的函数类似。
函数名字为:关键字operator后面接需要重载的运算符符号。
函数原型:返回值类型 operator操作符(参数列表)
注意:
1.作为类成员的重载函数时,其形参看起来比操作数数目少1成员函数的操作符有一个默认的形参this,限定为第一个形参
2.重载操作符必须有一个类类型或者枚举类型的操作数
3.* 、:: 、sizeof 、?: 、. 注意以上5个运算符不能重载。
先简单介绍下 全局的operator== 如何实现,以日期类为例
#includeusing namespace std; class Date { public: Date(int year = 1900, int month = 1, int day = 1) { _year = year; _month = month; _day = day; } bool operator==(const Date& d2)//this指针不能直接显示出来 { cout << "inside" << endl; return this-> _year == d2._year && _month == d2._month && _day == d2._day; } //private: int _year; int _month; int _day; }; // d1 = d2; -> d1.operator=(&d1, d2) bool operator==(const Date&d1 ,const Date& d2) { return d1._year == d2._year && d1._month == d2._month &&d1._day == d2._day; } void test1() { Date d1(2022,5,19); Date d2(d1); if (d1.operator==(d2)) { cout << "==" << endl; } if (d1 == d2)// 编译器会处理成对应重载运算符调用 if (d1.operator==(d2)) { cout << "==" << endl; } } int main() { test1(); return 0; } 结果: inside == //会优先调用类中的operator函数
2 .赋值运算符重载
介绍:以日期类为例,实现日期的+,-,=,++,--....等运算符的实现。
头文件中内容:
#pragma once #include#include using std::cout; using std::cin; using std::endl; class Date { public: bool isLeapYear(int year)//判断是否是闰年 { return (year % 4 == 0 && year % 100 != 0) || (year % 400 == 0); } int GetMonthDay(int year, int month);//判断月份天数 Date(int year = 1900, int month = 1, int day = 1) { _year = year; _month = month; _day = day; } bool operator==(const Date& d2); bool operator<(const Date& d2); bool operator<=(const Date& d2); bool operator>(const Date& d2); bool operator>=(const Date& d2); bool operator!=(const Date& d2); Date operator+(const int day); Date& operator+=(const int day); Date operator-(const int day); Date& operator-=(const int day); Date& operator++(int); Date& operator++(); Date& operator--(int); Date& operator--(); int operator-(const Date d2); void Print() { cout << _year <<"-" << _month <<"-" << _day << endl; } private: int _year; int _month; int _day; };
每个函数的实现:
#include"Date.h"
int Date::GetMonthDay(int year, int month)
{
assert(year >= 0 && month > 0 && month < 13);
const static int monthDayArray[13] = { 0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 };
if (month == 2 && isLeapYear(year))
{
return 29;
}
else
{
return monthDayArray[month];
}
}
bool Date:: operator==(const Date& d2)
{
return this->_year == d2._year
&& _month == d2._month
&& _day == d2._day;
}
bool Date::operator<(const Date& d)
{
if ((_year < d._year)
|| (_year == d._year && _month < d._month)
|| (_year == d._year && _month == d._month && _day < d._day))
{
return true;
}
else
{
return false;
}
}
bool Date::operator<=(const Date& d2)
{
return (*this == d2) || (*this < d2);
}
bool Date::operator>(const Date& d2)
{
return !(*this <= d2);
}
bool Date::operator>=(const Date& d2)
{
return !(*this < d2);
}
bool Date::operator!=(const Date& d2)
{
return !(*this == d2);
}
Date& 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 Date::operator+( int day)
{
Date ret(*this);
ret += day;
return ret;
}
Date& Date::operator-=(int day)
{
_day -= day;
while (_day <= 0)
{
--_month;
if (_month == 0)
{
_month = 12;
--_year;
}
_day += GetMonthDay(_year, _month);
}
return *this;
}
Date Date::operator-(int day)
{
Date ret(*this);
ret -= day;
return ret;
}
Date& Date::operator++(int) //前置++
{
*this += 1;
return *this;
}
Date& Date::operator++() //后置++
{
Date tmp(*this);
*this += 1;
return tmp;
}
Date& Date::operator--(int)
{
*this -= 1;
return *this;
}
Date& Date::operator--()
{
Date tmp(*this);
*this -= 1;
return tmp;
}
int Date:: operator-( Date d)
{
Date max = *this;
Date min = d;
int k = 1;
if (*this < d)
{
max = d;
min = *this;
int k = -1;
}
int n = 0;
while (min != max)
{
++n;
++min;
}
return n * k;
}



