C++静态成员函数和this指针详解
静态成员
静态成员就是在成员变量和成员函数前加上关键字static,称为静态成员
静态成员分为:
1.静态成员变量
所有对象共享同一份数据
在编译阶段分配内存
类内声明,类外初始化
示例:
#include
using namespace std;
class Person
{
public:
static int m; // 所有对象共享同一份数据
};
int Person::m = 0;// 类内声明,类外初始化
2.静态成员函数
所有对象共享一个函数
静态成员函数只能访问静态成员变量
#include
using namespace std;
class Person
{
public:
static void func()
{
cout << "static void func调用" << endl;
m_a = 100;//静态成员函数可以访问静态成员变量
//m_b=100,静态成员函数不可以访问非静态成员变量
//原因无法区分到底哪个是对象的m_b;
}
static int m_a;//静态成员变量
int m_b;
};
int Person::m_a = 0;
int main()
{
//1.通过对象访问
Person p;
p.func();
//2.通过类名访问
Person::func();
system("pause");
return 0;
}
静态成员函数可以访问静态成员变量
静态成员函数不可以访问非静态成员变量
私有权限的静态成员函数,也是访问不到的
成员变量和成员函数分开存储
在C++中,类内的成员变量和成员函数分开存储
只有非静态成员变量才属于类的对象上
空对象:
#include
using namespace std;
class Person
{
};
void test01()
{
Person p;
//空对象占用内存空间为:1
//C++编译器会给每个空对象也分配一个字节空间,是为了区分空对象占内存的位置
//每个空对象也应该有独一无二的内存地址
cout << sizeof(p) << endl;
}
int main()
{
test01();
return 0;
}
输出结果:1
#include
using namespace std;
class Person
{
int m_a;//非静态成员变量 属于类的对象上
};
void test02()
{
Person p;
cout << sizeof(p) << endl;
}
int main()
{
test02();
}
输出结果:4
#include
using namespace std;
class Person
{
int m_a;//非静态成员变量 属于类的对象上
static int m_b; //静态成员变量 不属于类的对象上
};
void test02()
{
Person p;
cout << sizeof(p) << endl;
}
int main()
{
test02();
}
输出结果:4
与第二个对比可知:
静态成员变量 不属于类的对象上
#include
using namespace std;
class Person
{
int m_a;//非静态成员变量 属于类的对象上
static int m_b; //静态成员变量 不属于类的对象上
void func() {}//非静态成员函数 不属于类的对象上
static void func2() {} //静态成员函数也不会属于 类的对象上
};
int Person::m_b = 0;
void test02()
{
Person p;
cout << sizeof(p) << endl;
}
int main()
{
test02();
}
输出结果:4
结论:只有非静态成员变量才属于类的对象上
this 指针
每一个非静态成员函数只会诞生一份函数实例,也就是说多个同类型的对象会共用一块代码
那么问题是:这块代码是如何区分是哪个对象调用自己的呢?
C++通过提供的特殊的对象指针,this指针,解决上述问题,this 指针指向被调用的成员函数所属的对象,通俗的说,谁调用它,this就指向谁
this 指针是所有成员函数的隐含参数吗,不需要定义,可直接使用
this 指针的用途
1.当形参和成员变量同名时,可用this指针来区分
2.在类的非静态成员函数中返回对象本身,可用 return *this
1.当形参和成员变量同名时,可用this指针来区分
#include
using namespace std;
class Person
{
public:
void func(int age)
{
this->age = age; //
}
int age;
};
int main()
{
Person p;
p.func(18);
cout << p.age << endl;
system("pause");
return 0;
}
2.在类的非静态成员函数中返回对象本身,可用 return *this
#include
using namespace std;
class Person
{
public:
Person& func(Person&p)
{
this->age += p.age;
return *this;
}
int age;
};
int main()
{
Person p;
p.age = 10;
//链式编程思想
p.func(p).func(p).func(p);
cout << p.age << endl;
system("pause");
return 0;
}
空指针访问成员函数
C++中空指针是可以调用成员函数,但是也要注意有没有用到this指针
如果用到this指针,需要加以判断保证代码的健壮性
#include
using namespace std;
class Person
{
public:
void ShowPersonclass()
{
cout << "调用ShowPerclass()函数" << endl;
}
};
int main()
{
Person* p = NULL;
p->ShowPersonclass();
system("pause");
return 0;
}
通过空指针p是可以访问到成员函数(不带this指针的成员函数)
如下代码就是一个错误代码
#include
using namespace std;
class Person
{
public:
void ShowPersonname()
{
cout << m_name << endl; //此处出现了this指针
}
int m_name;
};
int main()
{
Person* p = NULL;
p->ShowPersonname();
system("pause");
return 0;
}
解析:
此处出现了this指针
cout << m_name << endl;
相当于
cout <
而this指针是一个空指针,所以会报错
为了增加代码的健壮性,我们因该做出如下改动
#include
using namespace std;
class Person
{
public:
void ShowPersonname()
{
if (this == NULL) //在此判断this是否是空指针
return;
cout << m_name << endl;
}
int m_name;
};
int main()
{
Person* p = NULL;
p->ShowPersonname();
system("pause");
return 0;
}
总结
本篇文章就到这里了,希望能够给你带来帮助,也希望您能够多多关注脚本之家的更多内容!
您可能感兴趣的文章:
- .NET Core系列之MemoryCache 初识
- 007手机一键Root(安机网一键Root) v3.0 官方最新版 一键ROOT您的Android手机
- 12306密码被盗了怎么办?12306密码外泄解决方法
- 12个字的qq网名
- 150M迷你型无线路由器怎么设置?
- 192.168.1.1打不开怎么办?路由器192.168.1.1打不开的原因以及解决办法
- 2011年电子报合订本 电子报 编辑部 中文 PDF版 [84M]
- 2015年1月15日小米新旗舰发布会现场图文直播
- 2016.3.1vivo Xplay5新品发布会现场视频直播 优酷直播
- 2016华为P9发布会视频直播地址 4月15日华为P9国行发布会直播