在C++中,如果声明类的成员函数时,在参数列(小括号)之后函数体(花括号)之前,加上修饰符const,则称该成员函数为类的常量成员函数。我们来看下面这个示例程序:
class complex { public: complex (double r = 0, double i = 0) : re (r), im (i) { } complex& operator += (const complex&); double real ( ) const {return re;} //常量成员函数 double imag ( ) const {return im;} //常量成员函数 private: double re, im; friend complex& __doapl (complex*, const complex&); };
C++中的函数分为会改变数据的和不会改变数据的,对于不会改变数据的函数一定要加上const. const既可以修饰函数,也可以修饰对象。
对于常量成员函数,有以下几条性质:
(1)常量对象只能调用它的常量成员函数,而不能调用普通成员函数;
(2)普通对象既可以调用常量成员函数,也可以调用普通成员函数;
(3)普通成员函数可以访问本类的常量成员函数;
(4)常量成员函数不可以访问本类的普通成员函数。
如果在主函数中存在:
{ complex c1(2,1); //普通对象 cout << c1.real(); cout << c1.imag(); }
是合法的,这就是性质1所描述的普通对象调用它的常量成员函数。
如果成员函数和对象为:
class complex { ... double real ( ) {return re;} //普通成员函数 double imag ( ) {return im;} ... } { const complex c1(2,1); //常量对象 cout << c1.real( ); //不合法 cout << c1.imag( ); }
这种调用是非法的,因为常量对象不可以调用普通成员函数,因为编译器会认为函数可能会改变常量对象的值。
参数传递:pass by value v.s. pass by reference (to const)
C++中参数传递的两种方式:传值,传引用。传值的实质就是形参是实参的拷贝,形参改变并不会改变实参的值。而传引用时形参和实参其实是同一种东西,改变形参的值同时也会改变实参的值。引用底层实质是指针常量,指向所引用的对象。C++中建议传引用。
返回值传递:return by value v.s. return by reference(to const)
在下面这个例子中:
class complex { public: complex (double r = 0, double i = 0) //pass by value : re (r), im (i) { } complex& operator += (const complex&); //return by reference && pass by reference double real ( ) const {return re;} double imag ( ) const {return im;} private: double re, im; friend complex& __doapl (complex*, const complex&); };
{ complex c1(2,1); complex c2; c2 += c1; cout << c2; }
“引用”和“指针”的异同:
相同点:
(1)都是地址的概念;
指针指向一块内存,它的内容是所指内存的地址;引用本身是目标变量的别名,对引用的操作其实就是对目标变量的操作。
不同点:
(1)指针是个实体,而引用只是个别名;
(2)引用使用时不需要解引用(*),而指针需要;
(3)引用只能在定义时初始化一次,之后不可变,而指针可变;
(4)引用没有const,指针有const;
(5)引用不能为空,指针可以为空;
(6)“sizeof引用”得到的是所指向的变量(对象)的大小,而“sizeof指针”得到的是指针本身(所指向的变量或对象的地址)的大小;
(7)指针和引用的自增(++)运算意义不一样;
(8)从内存分配上看:程序为指针变量分配内存区域,而引用不需要分配内存区域。