h5可以做网站么,网站建设实验报告总结,网站推广教程优化整站,官方网站的重要性✨✨ 欢迎大家来访Srlua的博文#xff08;づ#xffe3;3#xffe3;#xff09;づ╭❤#xff5e;✨✨ #x1f31f;#x1f31f; 欢迎各位亲爱的读者#xff0c;感谢你们抽出宝贵的时间来阅读我的文章。 我是Srlua小谢#xff0c;在这里我会分享我的知识和经验。づ3づ╭❤✨✨ 欢迎各位亲爱的读者感谢你们抽出宝贵的时间来阅读我的文章。 我是Srlua小谢在这里我会分享我的知识和经验。 希望在这里我们能一起探索IT世界的奥妙提升我们的技能。 记得先点赞后阅读哦~ 所属专栏C/C 欢迎访问我的主页Srlua小谢 获取更多信息和资源。✨✨ 目录
赋值运算符重载
运算符重载
赋值运算符重载
1. 赋值运算符重载格式
2. 赋值运算符只能重载成类的成员函数不能重载成全局函数
3. 用户没有显式实现时编译器会生成一个默认赋值运算符重载以值的方式逐字节拷贝。
前置和后置重载
赋值运算符重载
运算符重载
C为了增强代码的可读性引入了运算符重载运算符重载是具有特殊函数名的函数也具有其返回值类型函数名字以及参数列表其返回值类型与参数列表与普通的函数类似。
函数名字为关键字operator后面接需要重载的运算符符号。
函数原型返回值类型 operator操作符(参数列表)
注意 不能通过连接其他符号来创建新的操作符比如operator 重载操作符必须有一个类类型参数 用于内置类型的运算符其含义不能改变例如内置的整型不能改变其含义 作为类成员函数重载时其形参看起来比操作数数目少1因为成员函数的第一个参数为隐藏的this .* :: sizeof ?: . 注意以上5个运算符不能重载。这个经常在笔试选择题中出现。
#include iostream
using namespace std;// 全局的operator
class Date
{
public:Date(int year 1900, int month 1, int day 1){_year year;_month month;_day day;}//private:int _year;int _month;int _day;
};这里会发现运算符重载成全局的就需要成员变量是公有的那么问题来了封装性如何保证 这里其实可以用我们友元解决后续讲解或者干脆重载成成员函数。 bool operator(const Date d1, const Date d2)
{return d1._year d2._year d1._month d2._month d1._day d2._day;
}
void Test()
{Date d1(2018, 9, 26);Date d2(2018, 9, 27);cout (d1 d2) endl;
}int main()
{Test();return 0;
} class Date
{
public:Date(int year 1900, int month 1, int day 1){_year year;_month month;_day day;} bool operator(Date* this, const Date d2) 这里需要注意的是左操作数是this指向调用函数的对象 bool operator(const Date d2){return _year d2._year; _month d2._month _day d2._day;}
private:int _year;int _month;int _day;
};int main()
{Test();return 0;
}
赋值运算符重载
1. 赋值运算符重载格式
参数类型const T传递引用可以提高传参效率 返回值类型T返回引用可以提高返回的效率有返回值目的是为了支持连续赋值 检测是否自己给自己赋值 返回*this 要复合连续赋值的含义
class Date
{
public:Date(int year 1900, int month 1, int day 1){_year year;_month month;_day day;}Date(const Date d){_year d._year;_month d._month;_day d._day;}Date operator(const Date d){if (this ! d){_year d._year;_month d._month;_day d._day;}return *this;}
private:int _year;int _month;int _day;
};
2. 赋值运算符只能重载成类的成员函数不能重载成全局函数
class Date
{
public:Date(int year 1900, int month 1, int day 1){_year year;_month month;_day day;}int _year;int _month;int _day;
};
// 赋值运算符重载成全局函数注意重载成全局函数时没有this指针了需要给两个参数
Date operator(Date left, const Date right)
{if (left ! right){left._year right._year;left._month right._month;left._day right._day;}return left;
}
// 编译失败
// error C2801: “operator ”必须是非静态成员 原因赋值运算符如果不显式实现编译器会生成一个默认的。此时用户再在类外自己实现一个全局的赋值运算符重载就和编译器在类中生成的默认赋值运算符重载冲突了故赋值运算符重载只能是类的成员函数。 3. 用户没有显式实现时编译器会生成一个默认赋值运算符重载以值的方式逐字节拷贝。
注意内置类型成员变量是直接赋值的而自定义类型成员变量需要调用对应类的赋值运算符重载完成赋值。
class Time
{
public:Time(){_hour 1;_minute 1;_second 1;}Time operator(const Time t){if (this ! t){_hour t._hour;_minute t._minute;_second t._second;}return *this;}
private:int _hour;int _minute;int _second;
};
class Date
{
private:// 基本类型(内置类型)int _year 1970;int _month 1;int _day 1;// 自定义类型Time _t;
};
int main()
{Date d1;Date d2;d1 d2;return 0;
} 既然编译器生成的默认赋值运算符重载函数已经可以完成字节序的值拷贝了还需要自己实现吗 这里会发现下面的程序会崩溃掉这里就需要我们深拷贝去解决。
#include iostream
using namespace std;
typedef int DataType;
class Stack
{
public:Stack(size_t capacity 10){_array (DataType*)malloc(capacity * sizeof(DataType));if (nullptr _array){perror(malloc申请空间失败);return;}_size 0;_capacity capacity;}void Push(const DataType data){// CheckCapacity();_array[_size] data;_size;}~Stack(){if (_array){free(_array);_array nullptr;_capacity 0;_size 0;}}
private:DataType* _array;size_t _size;size_t _capacity;
};
int main()
{Stack s1;s1.Push(1);s1.Push(2);s1.Push(3);s1.Push(4);Stack s2;s2 s1;return 0;
}
这段代码中的 Stack 类缺少拷贝构造函数和赋值运算符重载因此在执行对象拷贝时会出现浅拷贝的问题导致两个对象共享同一块内存。当其中一个对象析构时另一个对象所指向的内存就会变成非法内存从而导致程序崩溃。
要解决这个问题可以手动实现深拷贝。具体来说需要重载拷贝构造函数和赋值运算符将原始对象中的数据复制到新对象中并使用新的内存空间。
注意如果类中未涉及到资源管理赋值运算符是否实现都可以一旦涉及到资源管理则必须要实现。 前置和后置重载 class Date
{
public:Date(int year 1900, int month 1, int day 1){_year year;_month month;_day day;}// 前置返回1之后的结果注意this指向的对象函数结束后不会销毁故以引用方式返回提高效率Date operator(){_day 1;return *this;}// 后置// 前置和后置都是一元运算符为了让前置与后置形成能正确重载// C规定后置重载时多增加一个int类型的参数但调用函数时该参数不用传递编译器自动传递// 注意后置是先使用后1因此需要返回1之前的旧值故需在实现时需要先将this保存一份然后给this 1而temp是临时对象因此只能以值的方式返回不能返回引用Date operator(int){Date temp(*this);_day 1;return temp;}
private:int _year;int _month;int _day;
};
int main()
{Date d;Date d1(2022, 1, 13);d d1; // d: 2022,1,13 d1:2022,1,14d d1; // d: 2022,1,15 d1:2022,1,15return 0;
} 希望对你有帮助加油
若您认为本文内容有益请不吝赐予赞同并订阅以便持续接收有价值的信息。衷心感谢您的关注和支持