什么是this指针
话不多说,先看引例:
struct Sales_data{
std::string isbn() {return bookNo;}
std::string bookNo;
}
int main()
{
......
Sales_data total;
......
total.isbn();
......
}
-
成员函数isbn()隐含参数 * this,指向调用当前成员函数isbn的对象total,即this=&total
当isbn()返回bookNo时,实际上它隐式地返回total.bookNo,就像我们书写了this->bookNo一样; -
this是一个指向非常量的常量指针,不能绑定常量对象(参见[[Code/限定符const用法详解|限定符const用法详解]]–指针的类型必须与其所指对象的类型保持一致),不能在一个常量对象上调用非常量函数
本例中,this的类型是Sales_data * const ,Sales_data是非常量,意味着this不能绑定const常量,当一个const常量调用成员函数isbn()时,就不能使用this指针,也就不能获得this指向的成员函数isbn(),即调用失败。
this与常量成员函数
因此,为了防止以上情况的发生,我们需要将this指针声明为指向常量的常量指针(但仍然可以指向非常量,因常量->非常量,参见[[Code/限定符const用法详解|限定符const用法详解]]),C++语言的做法是在isbn()后加一个const限定符,并将isbn()函数称为常量成员函数
struct Sales_data{
std::string isbn() const {return bookNo;}
std::string bookNo;
}
int main()
{
......
Sales_data total;
......
total.isbn();
......
}
//相当于
//std::string Sales_data::isbn(const Sales_data *const this){return bookNo};
即,const实际上是对* this指针类型的修改
[!NOTE] NOTE
this指针是指向常量的指针,也就是说,函数内的成员不能通过this指针被改变,即这个函数的成员是常量成员(不能被改变)
this与重载函数
然而,这样做还是不够妥当。
当isbn()成为常量成员函数后,则isbn()函数不能再对普通函数进行调用:
struct Sales_data{
void display(std::ostream &os) const {os<<bookNo;}
std::string isbn() const {return bookNo;}
std::string bookNo;
}
int main()
{
......
Sales_data total;
......
total.isbn();
......
total.isbn().display();//ERROR
......
}
isbn()是一个常量成员函数,代表隐式参数* this是一个指向常量的常量指针,会返回一个常量(若为total),而非常量函数display()的隐式参数* this(指向非常量的常量指针)本应指向调用display()的对象total,但total是一个常量,而不是非常量,矛盾。即调用失败。
为了解决这个问题,我们需要重载display()函数。
struct Sales_data{
Sales_data &display(std::ostream &os)
{do_display(os);return *this;}
const Sales_data &display(std::ostream &os)
{do_display(os);return *this;}
//前面的const代表函数返回常量类型,后面的const代表调用display()函数的必须是const类型(即this指针指向的是const)
void do_display(std::ostream &os) const {os<<bookNo;}
std::string isbn() const {return bookNo;}
std::string bookNo;
}
int main()
{
......
Sales_data total;
......
total.isbn();
......
total.isbn().display();//NO ERROR
//isbn()是常量函数,调用常量版本的display();
......
}
[!NOTE] Note:
只能在一个常量对象上调用const成员函数!
今天的分享就到这儿啦,如果对你有帮助,希望可以动动小手,给博主点个不要钱的赞奥~
如果有什么疑惑,也欢迎在文章下留言与博主一起讨论~