#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;
}
effective C++学习---条款3:尽可能使用const
最新推荐文章于 2024-05-23 10:22:40 发布