目录
一、this指针
1.this的概念
this指针是一个特殊的,只在类内部(即成员函数、构造函数、析构函数中使用)存在,指向的当前类在外部的对象的地址。
this指针是个特殊的指针,存放的是当前对象的首地址。
指针原理:在调用成员的时候,编译器会用this来调用成员。哪个对象调用成员函数,this指针就指向哪个对象。
这里跑一下this。
#include <iostream>
using namespace std;
class Test{
public:
//成员函数
void show(){
cout<<this<<endl;
}
};
int main()
{
Test t;
t.show();
cout<<&t<<endl;
Test * t2=new Test;
cout<<t2<<endl;
t2->show();
}
运行结果如下图:
这里我们看到this打印出来的和直接取地址出来的结果是一样的。
2.this指针的作用
2.1 区分重名的成员变量与局部变量(在类中调用成员)
判断this指针的指向,只需要this指针所在的函数被哪个对象调用,this指向的就是这个对象。
这里有一个this的经典案例,用this来区分局部变量。
class Student{
private:
string name;
public:
Student(string name){
//name=name; //这里参数给参数 属性没有拿到值
this->name=name; //this->name 代表当前对象的name属性
}
string getName(){
return name;
}
};
2.2 *this 表示引用整个对象本身
当函数的返回值是当前类的引用时,*this表示的是this指针指向的对象本身,可以作为返回值使用,这样的函数支持链式调用。
如果一个类的成语函数返回值是当前类的引用,表示该函数支持“链式调用”,可以连续调用,像一条锁链一样。
链式调用举例:
#include <iostream>
using namespace std;
class Value{
private:
int value;
public:
Value(int value){
this->value=value;
}
Value& addValue(int n){
this->value=this->value+n;
return *this; //*this是当前对象
}
void show(){
cout<<value<<endl;
}
};
int main()
{
Value v(5);
v.show();
v.addValue(5);
v.addValue(5);
v.show(); //15
v.addValue(5).addValue(5).addValue(5);//链式调用
v.show(); //30
}
二、static关键字
1. 静态局部变量
static修饰的局部变量,所有这个类的所有对象共享,只有一份
第一次函数调用的时候,静态局部变量进行初始化。生命周期直到程序结束
2. 静态成员变量
static关键字修饰的成员变量
- 在程序运行时创建,在程序运行结束时销毁
- 必须类中声明,类外初始化
- 类中所有对象共享使用,在对象创建之前就已经存在
- 公共权限下的静态成员可以 类::的方式访问
#include <iostream>
using namespace std;
class Test{
public:
static int a;
};
int Test::a=10;
int main()
{
//static成员在对象未创建时已经存在
cout<<Test::a<<endl;
Test t1;
cout<<t1.a<<" "<<&t1.a<<endl;
Test t2;
cout<<++t2.a<<" "<<&t2.a<<endl;
Test * t3=new Test;
cout<<t3->a<<" "<<&(t3->a)<<endl;
}
运行结果如下,可以看出还未创建对象,已经就可以打印a的值。
3. 静态成员函数
特点:
- 和类相关,在对象创建前就可以调用
- 静态函数只能访问静态成员,不可以访问非静态成员 ,因为没有this指针
- 声明和定义分离的时候,static关键字只需要加在声明处
三、const关键字
1. const修饰局部变量(掌握)
通常情况下const修饰的局部变量表示常量,不允许进行修改。
#include <iostream>
using namespace std;
class Test{
public:
void method(const int a)
{
cout<<a<<endl;
//a++; //只读 不允许修改
}
};
int main()
{
Test t;
t.method(10);
}
2. const修饰成员变量 (掌握)
特点:
1.在运行时不允许修改
2.必须初始化,初始化可以通过初始化列表或者直接属性赋值,不能通过构造函数赋值。
一般在对象使用过程中,其数据成员成员不允许修改,可以用const来修饰
#include <iostream>
using namespace std;
class Test{
public:
const int a=20;
Test(int n):a(n){}
};
int main()
{
Test t(10);
cout<<t.a<<endl;
//cout<<++(t.a)<<endl; //const成员不允许修改
}
3. 常成员变量练习
封装圆类 属性有半径R. 对象使用过程中,PI值应保持不变,所以可以为const成员变量
#include <iostream>
using namespace std;
class Circle{
private:
double r;
const double PI;
public:
Circle(double n):r(n),PI(3.14) {}
double area(){
return PI*r*r;
}
};
int main()
{
Circle c1(10);
cout<<c1.area()<<endl;
}
4. const修饰成员函数(掌握)
目的是为了实现数据保护,常函数只能访问数据,但是不能进行修改。
特点:1.可以访问非const成员变量,但是不能修改
2.不能访问非const函数
#include <iostream>
using namespace std;
class Test{
private:
int a =10;
public:
void getA(){
a++;
cout<<a<<endl;
}
void setA(int n){
a=n;
}
void const_method() const
{
cout<<a<<endl;
//a++; 不允许修改
//setA(20); 不能访问非const函数
}
};
int main()
{
Test t;
t.const_method();
t.getA();
}
5. const修饰对象(熟悉)
特点:只允许访问const成员 ,不允许修改成员变量,不允许访问非const成员函数
const修饰对象可以写在类名前,也可以写在类名后
#include <iostream>
using namespace std;
class Test{
private:
int a =10;
public:
void getA(){
cout<<a<<endl;
}
void setA(int n){
a=n;
}
void const_method() const
{
cout<<a<<endl;
}
};
int main()
{
Test t;
t.const_method();
t.getA();
//const修饰对象
const Test t2;
//t2.setA(30); //错误 不允许访问非const函数
t2.const_method();
Test const t3;
//t3.setA(40); //错误 不允许访问非const函数
t3.const_method();
}