effective C++学习---条款3:尽可能使用const

#define _CRT_SECURE_NO_WARNINGS
#include<iostream>
#include<vector>
#include<string>
using namespace std;

/*
const的使用就是在告诉编译器和程序的使用者,某个值应该保持不变
这样编译器和使用者都会来遵守这项规则
*/

//const修饰指针
void test01()
{
	char greeting[] = "Hello";
	char *p = greeting;
	const char *p1 = greeting;//指向的事物不能改变
	char const  *p2 = greeting;//与上面的写法等价
	char * const p3 = greeting;//指向不能改变
	const char *const p4 = greeting;//指向和指向的事物都不能改变
}

//const用在迭代器上时,迭代器就相当于T*指针
void test02()
{
	vector<int > vec;
	//指向不能变
	const vector<int >::iterator it = vec.begin();
	//指向的内容不能变
	vector<int > ::const_iterator cit = vec.begin();
}

//const在函数声明中的使用
//函数返回值用const修饰
class Ration
{
public:
	int a;
	int b;
	Ration(int a, int b)
	{
		this->a = a;
		this->b = b;
	}
};
//表示返回的对象不能被修改
 const Ration operator*(const Ration& lhs, const Ration& rhs)
{
	return  Ration(lhs.a*rhs.a, lhs.b*rhs.b);
 }
 //const修饰函数形参,表示传进来的参数不能被更改
 int test03( const int a ,const int b)
 {
	 //a++;该操作是不被允许的
	 return a > b ? a : b;
 }

 //const作成员函数
 class TextBlock{
 public:
	 TextBlock(string text){ this->text = text; }
	 /*
	 对于以下的重载要说明以下,如果只是返回值不同是不能构成重载的
	 在第一个函数声明后加const表示只有const的类对象才能调用它
	 这样两个函数才能够成重载条件
	 */
	 const char& operator[](size_t position) const{
		 //后一个const表示在函数体中不能对类的成员变量进行修改
		 //text = "as";
		 text2 = "as";//const成员函数只能对static变量进行更改,因为static变量时属于整个类的
		 return text[position];
	 }

	 char& operator[](size_t position){
		 
		 //没有const修饰时是可以对成员变量进行修改的
		 //text = "as";
		 return text[position];
	 }
 private:
	 string text;
	 static string text2;
 };
 void test04()
 {
	 TextBlock tb("Hello");
	 cout << tb[0] << endl;//调用的是返回char&的重载函数
	 tb[0] = 'a';
	 const TextBlock ctb("World");//调用的是返回const char &的重载函数
	 cout << ctb[0] << endl;
	 //ctb[0] = 'a';会报错
 }
 
 /*
 下面的一种写法,用const修饰类函数,但是返回值没有用const修饰
 这样就回产生这样的情况,原本写程序的人是不想类成员变量被更改的
 但是返回给一个不安全的对象了,该对象可以对成员变量进行更改
 */
 class CTextClock{
 public:
	 CTextClock(char *ppText)
	 {
		 pText = new char[6];
		 //strcpy(ppText, pText);
		 pText = ppText;
	 }

	 char & operator[](size_t position) const{
		 return pText[position];
	 }
 private:
	 char *pText;
 };
 void test05()
 {
	 //可以对const对象进行保护的成员变量进行更改
	 //有一种const的作用被化解掉了
	 char *pp = "Hello";
	 const CTextClock cctb(pp);
	 
	 char *pc = &cctb[0];
	 cctb[1] = 'Q';
	 *pc = 'J';
	 cout << cctb[0] << cctb[1] << endl;
	 
 }
 
 //如果类中只有部分的成员变量需要const成员函数来保护
 //就可以引入mutable关键字
 class CTextBlock2{
 public:
	 size_t length() const;
 private:
	 char *pText;
	 mutable size_t textLength;
	 mutable bool lengthIsValid;
 };
 //mutable修饰后就释放了const成员函数对成员变量的控制
 //使得变量总是可以被更改
 size_t CTextBlock2::length() const
 {
	 if (!lengthIsValid)
	 {
		 textLength = strlen(pText);
		 lengthIsValid = true;
	 }
	 return textLength;
 }
 /*
 以下如果在重载函数中药做一些其他操作,那么在重载的时候这些操作就
 被执行了很多次,为了改善这种情况,我们采用一个函数来调用其他函数
 的做法,但是下面的两个函数一个是带const且返回值也是带const的,
 如果要在普通函数的调用它,就要先用static_const为this增加const,
 来调用const成员函数,然后将返回值中带的const用const_cast去掉。
 
 注意:这里用const函数调用普通函数的反向操作是不可行的,因为这样不安全
 const成员函数的本意是不改变成员变量的,但是如果应用了一个普通
 函数,就达不到这种目的了。
 */
 class TextBlock3{
 public:
	 const char &operator[](size_t position) const
	 {
		 //在此处进行了一些其他操作

		 return text[position];
	 }
	 //将op[]返回值的const移除,为*this加const,调用const op[]
	 char & operator[](size_t position)
	 {
		 return
			 const_cast<char &>(
			 static_cast<const TextBlock3&>(*this)[position]
			 );
	 }

 private:
	 string text;
 };


int main()
{
	Ration r1(2,3),r2(4,5),r3(9,8);
	r1 = r2;
	//如果重载*运算符时,返回值没有用const修饰,一下这种非法
	//赋值是可以进行的,这就是返回const值的意义。
	//r1*r2 = r3;

	
	system("pause");
	return 0;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值