const成员函数

const成员函数

  • const修饰成员函数的时候,const需要放在成员函数的后面,不能放在一开始,如果放在一开始的话,那么const其实是在修饰成员函数的返回值,而不是在修饰成员函数了
    在这里插入图片描述
  • const成员函数中不能修改成员变量
    在这里插入图片描述
  • 普通成员函数中可以修改成员变量
    在这里插入图片描述
  • 到底要不要使用const去修饰成员函数,就看你的函数中的变量需不需要被修改,如果希望其被修改的话,还是不要给成const,因为给成const的话,就不能去修改他了
    在这里插入图片描述
    在这里插入图片描述
    在这里插入图片描述
const修饰类的成员函数
  • 将const修饰的类成员函数称之为const成员函数,const修饰类成员函数,实际修饰该成员函数隐含的this指针,表明在该成员函数中不能对类的任何成员进行修改
    在这里插入图片描述
看下面的代码
class Date
{
public:
	Date(int year = 1900, int month = 1, int day = 1)
	{
		_year = year;
		_month = month;
		_day = day;
		cout << "Date(int,int,int):" << this << endl;
	}

	Date(const Date& d)
	{
		_year = d._year;
		_month = d._month;
		_day = d._day;
		cout << "Date(Date&):" << this << endl;
	}

	// d1 = d2 = d3;
	Date& operator=(const Date& d)
	{
		if (this != &d)
		{
			_year = d._year;
			_month = d._month;
			_day = d._day;
		}

		return *this;
	}

	// 可读可写
	// Date* const  this
	void TestFunc1()
	{
		//this = nullptr;
		this->_day++;
	}

	// 在该函数中不能修改当前对象的成员变量
	// const修饰this指针
	// const Date* const this;
	void TestFunc2()const
	{
		this->_day++;
		//_year++;
		//_month++;
	}

	// 只读操作:const Date* const
	void TestFuncWithConst()const
	{
		//TestFunc1(/*this*/);   // Date* const
	}

	// Date* const:可读可写
	void TestFuncWithoutConst()
	{
		TestFunc2(); // const Date* const: 只读
	}

	// (1+2)*3 ---> 12+3*
	~Date()
	{
		cout << "~Date():" << this << endl;
	}

	Date* operator&()
	{
		return this;
	}

	// Date* p = &d2;
	const Date* operator&()const
	{
		return this;
	}

private:
	int _year;
	int _month;
	mutable int _day;
	//但是有些时候,我还是希望有些值是可以变化的
	//加上const之后修改成员函数,那么成员函数里面所有的值都不能发生变化了
	//如果我希望有些值仍然是可以修改的话,那么我可以再某些变量的前面加上mutable
	//加上mutable之后就表明这个变量可以在const所修饰的成员变量中被修改
};

int main()
{
	Date d1(2019, 3, 24);
	const Date d2(2019, 3, 25); // 常量:d2中的内容不允许被修改
	cout << &d2 << endl;
	//d2.TestFunc1();  // TestFunc1成员函数:普通的成员函数,在函数中可以修改当前对象的成员
	d1.TestFunc1();
	d1.TestFunc2();
	return 0;
}
  • 但是有些时候,我还是希望有些值是可以变化的,加上const之后修改成员函数,那么成员函数里面所有的值都不能发生变化了,如果我希望有些值仍然是可以修改的话,那么我可以再某些变量的前面加上mutable,加上mutable之后就表明这个变量可以在const所修饰的成员变量中被修改
请思考下面的几个问题
这两个默认成员函数一般不用重新定义 ,编译器默认会生成。
  1. const对象可以调用非const成员函数吗?
  • 不可以,原因在于用const所修饰的变量本质上是一个常量,所以也就是说常量中的内容是不可以被修改的,但是普通的成员函数,在函数中可以修改当前对象的成员,所以两者是互相矛盾的,所以无法调用
    在这里插入图片描述
  1. 非const对象可以调用const成员函数吗?
  • 答案是可以的,因为普通类型的对象既可以修改成员变量的值,也可以不去修改成员变量的值,那到底要不要修改,根据情况而定就可以了。
    在这里插入图片描述
  1. const成员函数内可以调用其它的非const成员函数吗?
  • 是不可以的,因为如果你把一个函数声明为const类型的函数,那么就说明这个函数是只读的,是不可以修改的,而非const的成员函数是可读可写的
  1. 非const成员函数内可以调用其它的const成员函数吗?
  • 可以,因为外层函数的类型是 Date* const:可读可写,而内层函数的类型是const Date* const: 只读,外层可以修改也可以不修改,到底要不要修改,根据具体情况而定就可以了
取地址及const取地址操作符重载
// Date* p = &d2;
const Date* operator&()const    //如何第一个const没有加的话,代码是不能通编译的
{
	return this; 
	//因为要返回的是指针,但是如果返回的只是类类型的指针的话是不可以的,因为this指针是const类型的
	//所以返回值的前面也要加上const才可以
}
int main()
{
	Date d1(2019, 3, 24);
	const Date d2(2019, 3, 25); // 常量:d2中的内容不允许被修改
	cout << &d2 << endl;
	//d2.TestFunc1();  // TestFunc1成员函数:普通的成员函数,在函数中可以修改当前对象的成员
	d1.TestFunc1();
	d1.TestFunc2();
	return 0;
}
class Date
{
public :
Date* operator&()
{
	return this ;
}
const Date* operator&()const
{
	return this ;
}
private :
	int _year ; // 年
	int _month ; // 月
	int _day ; // 日
};
  • 这两个运算符一般不需要重载,使用编译器生成的默认取地址的重载即可,只有特殊情况,才需要重载,比如想让别人获取到指定的内容
程序的运行结果是什么
class Date
{
public:
	Date(int year = 1900, int month = 1, int day = 1)
	{
		_year = year;
		_month = month;
		_day = day;
		cout << "Date(int,int,int):" << this << endl;
	}

	Date(const Date& d)
	{
		_year = d._year;
		_month = d._month;
		_day = d._day;
		cout << "Date(Date&):" << this << endl;
	}

	// d1 = d2 = d3;
	Date& operator=(const Date& d)
	{
		cout << this << "=" << &d << endl;
		if (this != &d)
		{
			_year = d._year;
			_month = d._month;
			_day = d._day;
		}

		return *this;
	}

	~Date()
	{
		cout << "~Date():" << this << endl;
	}


	int _year;
	int _month;
	int _day;
};

Date TestDate(Date& d)
{
	Date temp(d);
	temp._day += 1;
	return d;
}

void TestDate()
{
	Date d1(2019, 3, 24);
	Date d2(d1);
	d1 = TestDate(d2);
}

int main()
{
	TestDate();
	return 0;
}
  • 打印结果如下所示:
    在这里插入图片描述
    在这里插入图片描述
class Date
{
public:
	Date(int year = 1900, int month = 1, int day = 1)
	{
		_year = year;
		_month = month;
		_day = day;
		cout << "Date(int,int,int):" << this << endl;
	}

	Date(const Date& d)
	{
		_year = d._year;
		_month = d._month;
		_day = d._day;
		cout << "Date(Date&):" << this << endl;
	}

	// d1 = d2 = d3;
	Date& operator=(const Date& d)
	{
		cout << this << "=" << &d << endl;
		if (this != &d)
		{
			_year = d._year;
			_month = d._month;
			_day = d._day;
		}

		return *this;
	}

	~Date()
	{
		cout << "~Date():" << this << endl;
	}


	int _year;
	int _month;
	int _day;
};

Date& TestDate(Date& d)
{
	Date temp(d);
	temp._day += 1;
	return d;
}

void TestDate()
{
	Date d1(2019, 3, 24);
	Date d2(d1);
	d1 = TestDate(d2);
}

int main()
{
	TestDate();
	return 0;
}
  • 结果如下所示:
    在这里插入图片描述
const 重载

在这里插入图片描述

  • 上面的两个函数是可以形成重载的,之所以可以形成重载是因为有const进行修饰,因为一旦加了const进行修饰的话,两个函数的this指针的类型就不一样了,这也就是为什么两个函数可以形成重载的原因
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值