c++的this指针与常函数
this指针与常函数
成员函数是如何区别调用它的对象?
#include <iostream> using namespace std; class Test { const int num; public: Test(int num):num(num) {} void show(void) { cout << num << " " << &num << endl; } }; int main(int argc,const char* argv[]) { Test t1(1234), t2(5678); t1.show(); t2.show(); }
C语言中我们如何解决该问题:
由于C语言中的结构没有成员函数,只能定义普通函数,取函数名时,让它与结构有关联,然后在函数的第一个参数把结构变量的地址传递过来,从而区别每个调用它的结构变量。
在C++语言中该问题由编译器帮忙解决:
1、C++语言中的结构、联合、类可以定义成员函数,成员函数都会有一个隐藏的参数。
2、该参数就是个地址,也叫this指针,可以显式使用。
3、使用结构、联合、类对象可以直接调用成员函数时,编译器会自动计算对象的地址隐式的传递给成员函数。
4、所以在成员函数中可以区分是哪个对象调用了它,并且在成员函数内访问成员变量时,编译器帮我们隐式在每个成员变量前增加了this->,所以可以区别出每个对象的成员变量。
5、由于成员函数参数列表中都隐藏着this指针,所以普通的成员函数无法作为回调函数使用。
#include <iostream> #include <pthread.h> #include <signal.h> using namespace std; class Test { int num; public: Test(int num):num(num){ } void* run(Test* this,void* arg) { } void sigint(int signum) { } void show(void) { cout << num << " " << &num << endl; } }; int main(int argc,const char* argv[]) { signal(SIGINT,Test::sigint); pthread_t tid; pthread_create(&tid,NULL,Test::run,NULL); return 0; }
6、显式使用this指针可以解决函数参数与成员变量同名的问题。
#include <iostream> #include <pthread.h> #include <signal.h> using namespace std; class Test { int num; public: Test(int num):num(num){ } void setNum(int num) { this->num = num; cout << this->num << " - " << &this->num << endl; } void show(void) { cout << num << " " << &num << endl; } }; int main(int argc,const char* argv[]) { Test t1(1234), t2(5678); t1.show(); t2.show(); t1.setNum(6666); t1.show(); }
常对象与常函数
什么是常函数
在成员函数的参数列表的末尾(小括号后面),用const修饰,这种成员就叫常函数。
class 类名 { public: // 常函数 返回值 函数名(参数列表) const { } };
常函数的特点:
常函数隐藏的this指针具有cosnt属性。
什么是常对象
在定义结构、联合、类对象时,使用const修饰,这种对象就叫常对象。
const 类名 对象名; const 类名* 指针变量 = new 类名;
常对象的特点:
使用常对象调用成员函数时,编译器计算出的对象地址(this)也具有const属性。
常对象有常函数的局限性:
1、常对象不能调用普通成员函数,只能调用常函数(构造函数和析构函数除外),但普通对象既可以普通成员函数,也可以调用常函数。
2、在常函数中不能显式修改成员变量,并且也不能调用普通的成员函数,只能调用常函数。
3、如果类的对象一定会被const修饰,那么它的成员函数都要定义为常函数。
4、如果类的对象可能被const修饰,也可能不修饰,那么它的成员函数要写两份,一份常函数,另一份普通成员函数。
mutable关键字的作用
如果常函数的const属性与函数的功能发生冲突,一定要修改成员变量,那么使用mutable关键字修饰一下需要在常函数中修改的成员变量。
#include <iostream> #include <pthread.h> #include <signal.h> using namespace std; class Test { mutable int num; public: Test(int num):num(num){ } void setNum(int num) const { this->num = num; cout << this->num << " - " << &this->num << endl; } void show(void) const { cout << num << " " << &num << endl; } }; int main(int argc,const char* argv[]) { const Test t(1234); t.show(); t.setNum(23456); t.show(); return 0; }
空类的对象为什么占用1字节内存?
1、因为C++中的空的结构、联合、类里面有隐藏的成员函数。
2、成员函数的参数列表中有隐藏this指针,调用这些成员函数时就需要计算出对象的地址传递给成员函数。
3、空的类对象至少要在内存中占据一个字节,才可以计算出this指针,传递成员函数,完成函数调用。