1:const member functions
class Complex
{
public:
Complex(double r = 0,double i = 0)
: re(r),im(i)
{}
double Getre() const { return re; }
double Getim() const { return im; }
private:
double re, im;
};
int main()
{
const Complex i(2, 1);
cout << i.Getre() << endl << i.Getim();
return 0;
}
const 从本质而言,相当于修饰符,如上述代码。前两个出现的const相当于,修饰函数,表明我这个函数不允许改变值。第三个const修饰 i 这个复数,含义相当于这个 i 是个常量。
为什么成员函数需要加const:
①从函数定义来说,在思考函数模板时第一步就给该考虑这个函数是否改变值,所以加上const仅是一个很容易的举措。
②若是不加const 之后,若使用者在定义一个const复数常量时候,
class Complex
{
public:
Complex(double r = 0,double i = 0)
: re(r),im(i)
{}
double Getre() { return re; }
double Getim() const { return im; }
private:
double re, im;
};
//错误样例
int main()
{
const Complex i(2, 1);//i为一个常量
cout << i.Getre(); //不一定为const的函数打印实部
return 0;
}
首先,这本身就十分矛盾,虽说自身很明确Getre()函数不存在改变值(修饰该函数说明里面不会发生任何副作用),但没有const修饰,如何让编译器去分辨呢? 如同一个例子,自己明确知道 自己面前是个 女(const)人,此时我告诉自己的朋友,自己面前有个 人,ta又如何判断是男是女呢?
2:pass by value or pass by reference(to const)
①:by value 相当于把数据整个打包,传到函数当中,对于空间占用会显得更大
②:by reference 相当于将该值的指针(引用)传进去,而指针只占4个字节,显然会更好。
③:by reference to const 若是把引用传到函数当中,会存在修改数据的情况,若是该函数只是对于数据进行处理的时候,便不能改变该值,可是又担心改变了,此时加上const修饰符,不仅满足了节约内存的问题,也使得担忧消失。
写两个函数来具体演示:
//定义结构体,用来储存书名跟书的页码
typedef struct
{
string name;
int page;
}Book;
//打印书名跟页码
void Print(Book a)
{
cout << a.name << ' ' << a.page << endl;
}
void Print2(const Book& a)
{
cout << a.name << ' ' << a.page << endl;
}
int main()
{
Book A = {"哈姆雷特",400}, B = {"他在云之南" ,350};
Print(A), Print(B);
Print2(A), Print2(B);
return 0;
}
因此,在写函数的时候,更多去用引用传递会更好。
3:return by value or return by reference(to const)
同理接下来写可以传引用也可以传值的两个函数
以及可以传值,但是不可以传引用(可以返回引用的话就可以返回值,但是尽量使用返回引用)
这四个函数能让你理解二者直接的不同
//将b的值加到a中然后返回a的引用
//其实这个举措是很没有必要的,因为将函数定义成void,传递进去的a的引用,所以简单的加上b也会改变a。
//但是使用返回值会让可读性更好,意思一目了然
int& sum(int& a, const int& b)
{
a += b;
return a;
}
//返回a与b的和
int sum(const int& a, const int& b)
{
return a + b;
}
//错误样例
int& sum1(const int& a, const int& b)
{
int c = a + b;
return c;
}
//返回a与b的和
int sum(const int& a, const int& b)
{
int c = a + b;
return c;
}
sum1错误也很容易理解,因为c变量是在sum1当中的局部变量,而在sum1函数结束时候,c变量就会被销毁,此时返回值为c变量的引用,很显然是错误的行为。
总结:返回值可以返回引用的:需要有一个生命周期长于该函数的一个变量可以作为存储数据。