C++六个默认成员函数(下)

1.运算符重载介绍

1.C++为了增强代码的可读性引入了运算符重载,运算符重载是具有特殊函数名的函数,也具有其返回值类型,函数名字以及参数列表,其返回值类型与参数列表与普通的函数类似。
2.函数名字为: 关键字operator后面接需要重载的运算符符号
3.函数原型: 返回值类型 operator操作符(参数列表)
如:bool operator<(const int n)

注意:
1.不能通过连接其他符号来创建新的操作符: 比如operator@
2.重载操作符必须有一个类类型参数
3.用于内置类型的运算符,其含义不能改变,例如: 内置的整型+,不能改变其含义
4.作为类成员函数重载时,其形参看起来比操作数数目少1,因为成员函数的第一个参数为隐藏的this指针

重载流插入和流输出

运算符重载中,参数顺序和操作数顺序必须一致
特别的:当出现重载流插入或者流输出时,建议重载为全局函数,否则用起来不符合逻辑

	//这么写才能转换(d1是一个日期类成员)
	d1.operator<<(cout);
	d1 << cout;

	//全局以后这么写就可以了 因为参数的前后位置原因
	cout << d1;

这里面又涉及了友元的概念(因为要访问类里的私有变量) 如下:

class Date
{
	//友元函数声明  可以访问内部成员
	friend ostream& operator<<(ostream& out, const Date& d);
	//由于成员函数默认的第一个参数为隐含的this指针 所以函数声明在全局
	friend istream& operator>>(istream& in, Date& d);
public:
	
private:
	int _year ;
	int _month ;
	int _day ;
}
//返回值为cout的原因是可以连续重载输出
ostream& operator<<(ostream& out, const Date& d)
{
	out << d._year << "年" << d._month << "月" << d._day << "日" << endl;
	return out;
}

istream& operator>>(istream& in, Date& d)
{
	in >> d._year >> d._month >> d._day;
	return in;
}

关于更多的重载

可以查看我的gitee中的date日期类的实现 包含了大部分的操作符重载
例如前置++ 和后置++
链接: 重载gitee地址

2.赋值运算符重载

  1. 赋值运算符重载格式
    1.参数类型:const T&,传递引用可以提高传参效率
    2.返回值类型:T&,返回引用可以提高返回的效率,有返回值目的是为了支持连续赋值
    3.检测是否自己给自己赋值
    4.返回*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 ;
}

关于返回值

关于返回值这里需要特殊说明
出了作用域,返回对象还在没有析构,那就可以用引用返回,减少拷贝返回对象生命周期到了,会析构,传值返回a.返回对象生命周期没到,不会析构,传引用返回

Date& operator=(const Date& d)
    {
        if(this != &d)
        {
            _year = d._year;
            _month = d._month;
            _day = d._day;
		}
		//注意这里的this是开辟在栈上的
		//是main函数创建的类中的 所以可以传引用返回
        return *this;
    }

返回值传引用主要是为了减少拷贝次数

Date func()
{
	Date d;
	return d;
}

以上代码的返回值是不是d呢?
注意:返回值并不是d ,d出了作用域都销毁了
这里会生成一个临时拷贝 返回临时对象作为返回值
并且临时变量具有常性
而不生成的方法就是引用返回 但是这里并不能这么做
因为之前已经说明被销毁了 引用也会被销毁

可以这么做

Date& func()
{
	static Date d;
	return d;
}

拷贝构造和赋值重载的一个区别

特别的:
1.拷贝构造 :一个已经存在的对象,拷贝给另一个要创建初始化的对象
2.赋值重载: 一个已经存在的对象,拷贝赋值给另一个已经存在的对象

==赋值运算符重载成全局函数,注意重载成全局函数时没有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;
}

注意:1.用户没有显式实现时,编译器会生成一个默认赋值运算符重载,以值的方式逐字节拷贝 , 和拷贝构造函数是一样的浅拷贝。
2.和其他默认成员函数一样:内置类型成员变量是直接赋值的,而自定义类型成员变量需要调用对应类的赋值运算符 重载完成赋值。

3.const成员函数

概念

【概念】:将const修饰的“成员函数”称之为const成员函数,const修饰类成员函数,实际修饰该成员函数隐含的this指针,表明在该成员函数中不能对类的任何成员进行修改

讨论

1.C++中的成员函数隐含的this指针中含有一个const 即: const (类名)* this
2.如果 void Print() const 就是双const 即: const (类名)* const this
3.此时既不能修改其内部的值 也不能修改所指向的地址
4.const默认写在函数声明的右侧

问题:

问题1const对象 可以调用 非const成员函数吗?

这个当然不可以。若 const对象去调用非const成员函数,会造成【权限放大】的现象,原本在类外const对象的内容是不可以修改的,但是到了函数内部却可以修改了,这是不被允许的

问题2非const对象 可以调用 const成员函数吗?

在这里插入图片描述
这个当然是可以的。非const对象本身就是可读可写的,那在函数内部你要去修改或者不修改都不会有影响(权限缩小)

取地址及const取地址操作符重载

class Date
{
public:
    //取地址&重载
	Date* operator&()
	{
		return this;
	}
    //const取地址&重载
	const Date* operator&()const
	{
		return this;
	}
private:
	int _year;
	int _month;
	int _day;
};

当然,如果我们自己不写&重载,编译器也会默认生成

一般不需要我们自己实现
除非不想让别人取到这个类型对象的真实地址

结尾

以下就是我对【C++】类的默认成员函数的理解,如果有不懂和发现问题的小伙伴,请在评论区说出来哦,同时我还会继续更新对C++ 类和对象的理解,请持续关注我哦!!!

  • 50
    点赞
  • 26
    收藏
    觉得还不错? 一键收藏
  • 22
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 22
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值