小记:静默如初,安之若素
1. this指针
1. 定义
类中的函数都隐藏一个该类类型的指针参数,名为this。
==》对于普通的成员函数,this指向调用该函数的对象
==》对于构造函数,this指向正在创建的对象
eg:
class A
{
public:
A(int i):m_i(i){}
void print(void)
{
cout << m_i << endl;
}/*print 编译后会变成类似下面:
void print(A* this)
{
cout << this->m_i <<endl;
}
*/
int m_i;
};
A a1(100);
A a2(200);
a1.print();//100
//A::print(&a1);
a2.print();//200
//A::print(&a2)
2. 需要显示适用this指针的场景
1)区分作用域
1 #include <iostream>
2 using namespace std;
3
4 class User
5 {
6 public:
7 //通过this指针区分成员变量和参数变量(只限在函数体)
8 User(const string &m_name, int m_age)
9 {
10 this->m_name = m_name;
11 this->m_age = m_age;
12 }
13
14 void who(void)
15 {
16 cout << m_name << " , " << m_age << endl;
17 cout<< this->m_name << " , " << this->m_age << endl;
18 }
19 /*
20 void who(User *this)
21 {
22 cout<< this->m_name << "," << this->m_age << endl;
23 }
24 */
25
26 private:
27 string m_name;
28 int m_age;
29 };
30
31 int main(int argc, char * argv[])
32 {
33 User u1("red1", 28);
34 cout << "&u1 = " << &u1 <<endl;
35 User u2("red2", 26);
36 cout << "&u2 = " << &u2 <<endl;
37 u1.who();//User::who(&u1);
38 u2.who();//User::who(&u2);
39
40 return 0;
41 }
~
2)从成员函数返回调用对象自身(必须加引用才能调用某个函数的自身)(常用)
1 #include <iostream>
2 using namespace std;
3
4 class Counter
5 {
6 public:
7 Counter(int num=0):m_num(num){}
8 //Counter&& add(Counter *this)
9 Counter& add(void)
10 {
11 //++this->m_num;
12 ++m_num;
12 //this指向调用对象,*this就是调用对象自身
13 return *this;//返回调用对象自身(返回自引用)
14 }
15 int m_num;
16 };
17
18 int main(int argc, char * argv[])
19 {
20 Counter cn(1);
21 //Counter::add(&cn);
22 cout << cn.m_num << endl;//1
23 cn.add().add().add();//级联函数
24 cout << cn.m_num << endl;//4
25
26 return 0;
27 }
3)从类的内部销毁对象自身
1 #include <iostream>
2 using namespace std;
3
4 class Counter
5 {
6 public:
7 Counter(int num=0):m_num(num){}
8 void destroy(void)
9 {
10 cout << this << endl;
11 delete this; //对象自销毁
12 }
13 int m_num;
14 };
15
16 int main(int argc, char * argv[])
17 {
18 Counter *pc = new Counter(123);
19 //...
20 cout << "pc = " << pc << endl;
21 cout << pc->m_num << endl;//123
22 //deleter pc;//常规使用指针的方法
23 pc->destroy();
24
25 return 0;
26 }
~
2 常成员函数
1. 定义:在一个成员函数参数表的后面加上const修饰,这个成员函数就是常成员函数(常函数)。
语法:
返回类型 函数名(形参表) const{//函数体} //针对普通成员函数
2. 常函数中的this指针是一个常指针,不能在常函数中修改成员变量的值。
1 #include <iostream>
2 using namespace std;
3
4 class A
5 {
6 public:
7 A(int data = 0):m_data(data){}
8 void print(void) const //常函数
9 {
10 //cout << m_data++ << endl;//error
11 cout << m_data << endl;
12 }
13 //与上面的print()函数等价
14 /*void print(const A* this) //常函数
15 {
16 //cout << m_data++ << endl;//error
17 cout << m_data << endl;
18 }*/
19
20 private:
21 int m_data;
22 };
23
24 int main(int argc, char *argv[])
25 {
26 A a(100);
27 a.print();//100
28 a.print();//100
29
30 return 0;
31 }
注:被mutable关键字修饰的成员变量可以在常函数中被修改
1 #include <iostream>
2 using namespace std;
3
4 class A
5 {
6 public:
7 A(int data = 0):m_data(data){}
8 /*正常情况下不能在常函数中修改m_data
9 但是如果m_data被mutable修饰就可以修改*/
10 void print(void) const //常函数
11 {
12 cout << m_data++ << endl;//error
13 //cout << m_data << endl;
14 }
15 //与上面的print()函数等价
16 /*void print(const A* this) //常函数
17 {
18 //cout << m_data++ << endl;//error
19 cout << m_data << endl;
20 }*/
21
22 private:
23 mutable int m_data;//mutable关键字
24 };
25
26 int main(int argc, char *argv[])
27 {
28 A a(100);
29 a.print();//100
30 a.print();//101
31
32 return 0;
33 }
- 常函数使用场景:非 常对象那既可以调用非 常函数,也可以调用常函数;但是常对象(也包括常引用,常指针)只能调用常函数,不能调用非 常函数。
1 #include <iostream>
2 using namespace std;
3
4 class A
5 {
6 public:
7 //void func1(const A* this)
8 void func1(void) const
9 {
10 cout << " 常函数 " << endl;
11 }
12 //void fun2(A* this)
13 void func2(void)
14 {
15 cout << "非常函数" << endl;
16 }
17 };
18
19 int main(int argc, char *argv[])
20 {
21 A a;//非 常对象
22 a.func1();//A::func1(&a), A*
23 a.func2();
24
25 const A a2 = a;//常对象
26 a2.func1();//A::func1(&a2), const A*
27 //a2.func2();//error
28
29 const A& ra = a;//常引用
30 ra.func1();
31 //ra.func2();//error
32
33 const A* pa = &a;//常指针
34 pa.func1();
35 //pa.func2();//error
36
37 return 0;
38 }
- 函数名和形参表相同的成员函数,其常版本和非 常版本可以构成有效的重载,常对象调用常版本,非常对象调用非 常版本。
1 #include <iostream>
2 using namespace std;
3
4 class A
5 {
6 public:
7 //void func(const A* this)
8 void func(void) const
9 {
10 cout <<"常函数版本 "<<endl;
11 }
12 //void fun(A* this)
13 void func(void)
14 {
15 cout << "非 常函数版本" <<endl;
16 }
17 };
18
19 int main(int argc, char *argv[])
20 {
21 A a1;
22 a1.func();//非 常函数版本
23 const A a2 = a1;
24 a2.func();//常函数版本
25 return 0;
26 }
~