类的成员函数

定义类的成员函数

尽管所有成员都必须在类的内部声明,但是成员函数体可以定义在类的内部也可以定义在类外。

定义在类的内部的函数隐式inline函数


引入this

成员函数通过一个名为this的额外的隐式参数来访问调用它的那个对象。当我们调用一个成员函数时,用请求该函数的对象地址初始化this。例如,如果调用

total.isbn()

则编译器负责把total的地址传给isbn的隐式参数this,可以等价地认为编译器将该调用重写为下面的形式:

//伪代码

Sales_data::isbn(&total)

 其中,调用Sales_data的isbn成员时传入了total的地址。

因为this的目的总是指向“这个”对象,所以this是一个常量指针


引入const成员函数

std:string isbn() const {return bookNo;}

紧随参数列表之后的const关键字,这里,const关键字的作用是修饰隐式this指针的类型。


   默认情况下,this的类型是指向类类型非常量版本的常量指针。例如在Sales_data成员函数中,this的类型是Sales_data *const。尽管this是隐式的,但它仍然需要遵循初始化规则,意味着(在默认情况下)我们不能把this绑定到一个常量对象上去。这一情况也就使得我们不能在一个常量对象上调用普通的成员函数。

   如果isbn是一个普通函数而且this是一个普通的指针参数,则我们应该把this声明为const Sales_data *const。毕竟,在isbn函数体内不会改变this所指的对象,所以把this设置为直线常量的指针有助于提高函数的灵活性。

   然而,this是隐式的并且不会出现在参数列表中,所以在哪儿将this声明成指向常量的指针就成为我们必须面对的问题。C++的做法是允许把const关键字放在成员函数的参数列表之后,此时,紧跟在参数列表之后的const表示this是一个指向常量的指针。

像这样使用const的成员函数被称作为常量成员函数(const member function)

    可以把isbn的函数体想成这样

    //伪代码,说明隐式的this指针是怎么工作的

    //this是一个指向常量的指针,因为isbn是一个常量成员

    std::string Sales_data::isbn(const Sales_data *const this)

    { return this->bookNo;}


常量对象,常量对象的引用或指针都只能调用常量成员函数。

任何不会修改数据成员的函数都应该声明为const类型。

const类对象只能调用被声明为const的成员函数,而普通的类对象可以调用非const或const成员函数

小结 

1)const成员函数可以访问非const对象的非const数据成员、const数据成员,也可以访问const对象内的所有数据成员;

2)非const成员函数可以访问非const对象的非const数据成员、const数据成员,但不可以访问const对象的任意数据成员;

3)作为一种良好的编程风格,在声明一个成员函数时,若该成员函数并不对数据成员进行修改操作,应心可能将该成员函数声明为const 成员函数。



补充:const限定符

cosnt限定符修饰的变量,试图修改该变量的值都被编译器视为错误。

除了两种例外情况(将在const章节和类型转换和继承中介绍,c++ primer 5th,p47),指针的类型和其所指向对象的类型必须匹配。

在初始化的过程中,不在乎类型是否为const,因为不会改变该对象。

const默认只在文件内有效,在多个文件中共享const对象,需要在变量定义和声明时都加上extern。


不允许一个非常量引用指向一个常量对象

const int ci = 1024;

int &r2 =ci;                            //错误,r2为非常量引用,ci为常量对象


允许用任意表达式作为初始值,初始化常量引用,只要该表达式可的结果可以装换成引用的类型。

int i =42;

const int &r1  = i;

const int &r2 = 42;

const int &r3 = r1*2;

int &r4 = r1*2;                       //错误不允许让一个普通的非常量引用指向一个常量对象


对于指针也类似,只不过指针是对象,多一些内容

指向常量的指针(pointer to const)不能改变所指向的对象的值。

想要存放常量对象的地址,只能使用指向常量的指针(这就是为什么对于定义常量成员函数,因为常量对象调用成员函数,我们需要将this声明为指向常量的指针,也就有了常量成员函数)。

const double pi = 3.14;

double *ptr = π                        //错误,ptr是普通的非常量指针,不能存放常量对象的地址

const double *cptr = π            //正确


与引用类似的的一种例外

允许一个指向常量的指针指向一个非常量对象。

double dval = 3.14;

cptr = &dval。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值