拷贝构造函数与运算符重载(c++详解) |
您所在的位置:网站首页 › 符能请吗 › 拷贝构造函数与运算符重载(c++详解) |
拷贝构造函数与运算符重载
拷贝构造函数引出拷贝构造函数
运算符重载引出运算符重载赋值运算符重载
拷贝构造函数引出
先给出日期类的定义: class Date { public: Date(int year=1900,int month=1, int day=1) { _year = year; _month = month; _day = day; } void print() { cout public: stack(int capacity=4) { _a = (int*)malloc(sizeof(int)*capacity); _capacity = capacity; _size = 0; } ~stack { free(-a); _capacity=0; _size=0; } private: int* _a; int _size; int _capacity; }; int main() { stack s1; stack s2(s1); return 0; }这里我们想干的是在建一个对象s2,这个对象也想s1一样有一样的一个一样大小的数组,但是我们发现 而且这个程序最后会崩溃,创建s2,s2后进系统上的栈,先出所以s2对象生命周期先结束,会调用我们写的析构函数(自己生成的析构函数不释放)释放对上的空间,而s1此时是浅拷贝,和他共用一个空间,生命周期结束,再次调用析构函数,又free了一次,完蛋。 由于日期类里面没有指针什么的,所以默认生成的就可以用,因为它只需要浅拷贝所有字节, 而栈里,则是必须我们要自己写一个拷贝构造实现深拷贝(要一块跟你一样大的空间,让指针指向自己的),因为不写,就出现了上述举例的情况 运算符重载引出C++为了增加代码的可读性引入了运算符重载。自定义类型就可以像内置类型一样去用运算符。需要我们自己定义运算符重载 Date d; d+1;//日期加一天 运算符重载运算符重载是具有特殊函数名的函数,也具有返回值类型,函数名字,及参数列表,其返回值类型与参数列表与普通函数类似。 函数名字:关键字operator后面接需要重载的运算符符号。 函数原型: 返回值类型 operator 后面接需要重载的运算符符号 注意: 不能通过连接其他符号创造新的操作符冲在操作符必须有一个类类型或者枚举类型的操作数用于内置类型的操作符其含义不能改变,例如内置的整形+,不能改变其含义作为类成员函数,其形参看起来比操作数数目少一,因为成员函数有个默认的形参this指向调用对象,限定为第一个形参。.* :: sizeof ?: . 以上五个运算符不能重载(面试选择题经常考)想用什么操作符去自己重载第一次写了这样,忘记了作为成员函数的时候,第一个参数已经有了就是隐含的this指针,指向调用对象。 开始的时候运算符函数形参写的是这样 const Date d2,虽然也可以,但是传递过去会调用拷贝构造函数。 但是脑子一混,把operator==函数当成了拷贝构造函数,还在想拷贝构造函数的形参是const Date d2的话不就无穷调用了吗。(zzz,你不重新写拷贝构造函数,人家默认生成的的参数肯定是引用类型的,不用你操心) 赋值运算符重载把d2的值赋值给d1,需要注意的是它与拷贝构造是不一样的。赋值说明的是,两个对象已经定义出来了。 Date d1; Date d2(2021,2,6); d1=d2;而拷贝构造则是将d1的值直接初始化给d2。两者是不一样的 Date d1; Date d2(d1); //赋值重载 void operator=(const Date& d) { //自己赋值自己没有意义 //开始写成这样,让对象比较。。还要写一个运算符重载函数比较 if(*this!=d) if(this!=&d) { _year = d._year; _month = d._month; _day = d._day; } }但是在我们的内置类型中是支持连续赋值的 比如说: int i,j,k; i=j=k=10;也就是说k=10,有一个返回值k,让j=k,返回j,又让i=j。 所以给我们的函数加上返回值,类型为类名,返回this所指向的对象 //赋值重载 Date operator=(const Date& d) { //自己赋值自己没有意义 if(this!=&d) { _year = d._year; _month = d._month; _day = d._day; } return *this; }当返回值为Date类型,*this传递给外面需要两次拷贝构造(先传给临时变量(Date类型),临时变量再给外面用于接收的变量) 当返回值为Date&,临时变量是返回值的别名,减少一次拷贝构造。形参做引用(总共一次)也减少一次拷贝构造。 所以下面这样写一共减少了两次拷贝构造。 //最终版赋值重载 Date& operator=(const Date& d) { //自己赋值自己没有意义 if(this!=&d) { _year = d._year; _month = d._month; _day = d._day; } return *this; }注意:返回值做引用有一个条件就是看你返回值的生命周期,假如this所指向的对象生命周期在本函数体内,那么this传给中间变量,此时this销毁,中间变量是个引用也跟着销毁。外面的变量接收不到它。但是在这里*this是d1对象,生命周期在main函数里,所以不用担心 当我们不写,他也会自动生成,不过默认生成的他也是只进行浅拷贝,只拷贝值,像之前写拷贝构造函数里的Static,里面的指针变量。当d1=d2时,两个对象里面的两个指针指向同一块空间,析构的时候释放两次,程序崩溃。 |
今日新闻 |
点击排行 |
|
推荐新闻 |
图片新闻 |
|
专题文章 |
CopyRight 2018-2019 实验室设备网 版权所有 win10的实时保护怎么永久关闭 |