3.2 成员函数
3.2.1 成员函数的定义
在面向对象程序设计中,类的成员函数也称为方法或服务,有两种定义方式。
一种是在声明类时就给出成员函数的定义,以这种方式定义的成员函数若符合内联函数的条件就会被处理为内联函数。例如,一个日期类的定义如下:
class Date{ int day,month,year; public: void init(int d,int m,int y){ day=d; month=m; year=y; } int getDay() {return day;} …… };
在类Date中,成员函数init()和getDay()直接在类的内部进行了定义,都是内联函数。
另一种定义方法,是在声明类时,只声明成员函数的原型,然后在类的外部定义成员函数。其定义方法是:
r_type class_name::f_Name(T1 p1, T2 p2,…);
其中,r_type是成员函数的返回类型,class_name是类名,::是域限定符,用于说明函数f_Name( )是class_name的成员函数,f_Name是成员函数名,T1、T2是参数类型,p1、p2是形式参数,在函数原型中它并无任何意义,可省略。
例如,Date类的成员函数init( )和getDay( )也可用下面的方法定义。
class Date{ int day,month,year; public: void init(int ,int ,int ); int getDay(); }; int Date::getDay() {return day;} inline void Date::init(int d,int m,int y) { day=d; month=m; year=y; }
注意:这里的init( )和getDay( )是有区别的,init()是内联函数,而getDay()不是。在C++中,若在类外成员函数的定义前加上关键字inline,该成员函数就被定义为内联函数。
说明:① 若采用类外方式定义成员函数,则类声明中成员函数原型中的形参名可以省略,只声明各个形参的类型;② 在类外定义成员函数时,成员函数的返回类型、函数名称、参数表必须与成员函数原型的声明完全相同,而且必须指出每个形参的名字;③ 在类外定义成员函数时,必须在成员函数名前面加上类名,并且在类名与成员函数之间用::间隔。
3.2.2 常量成员函数
在C++中,为了禁止成员函数修改数据成员的值,可以将它设置为常量成员函数。设置常量成员函数的方法是在函数原型的后面加上const,形式如下:
class x{ …… T f(T1,T1,…) const; …… };
其中,T是函数返回类型,f 是函数名,T1、T2…是各参数的类型。将成员函数设置为const类型后,表明该成员函数不会修改任何数据成员的值。例如:
class Employee{ char *name; double salary; public: void init(const char *Name,const double y); double getSalary() const; //常量函数,不能通过它修改name和salary char *getName()const; //常量函数,不能通过它修改name和salary void addSalary(double x) const; //常量函数,不能通过它修改name和salary }; void Employee::init(const char *Name, const double y) { //本函数的参数是常量,但不是常量成员函数 name=new char[strlen(Name)+1]; strcpy(name,Name); salary=y; } double Employee::getSalary() const{//正确 return salary; } void Employee::addSalary(double x) const{ salary+=x; //错误,常量成员函数不能修改数据成员 } char *Employee::getName(){ //错误,缺少const,与类中声明的原型不符 return name; }
说明:① 只有类的成员函数才能定义为常量函数,普通函数不能定义为常量函数。下面的函数定义是错误的:
int f(int x) const{ //错误,普通函数不能指定为const int b=x*x; return b; }
② 常量参数与常量成员函数是有区别的,常量参数限制函数对参数的修改,但与数据成员是否被修改无关。