C++ 一些学习笔记(八)类和对象-C++对象模型和this指针
主要是针对之前学习C的时候一些知识点的遗漏的补充,还有一些我自己觉得比较重要的地方。
本文章的主要内容是关于C++对象模型和this指针的。
1.成员变量和成员函数分开存储
C++中,类内的成员变量和成员函数分开存储
只有非晶态成员变量才属于类的对象上
空对象的大小会考,空对象的大小为1
class Person{
public:
mA=0;
}
int mA;//非静态成员变量属于类,计算内存只计算这部分,下边的三个都不算
static int mB;//静态成员变量不属于类的对象上
void func(){}//非静态成员函数不属于类的对象上
static void func2(){}//静态成员函数不属于类的对象上
};
int Person::mB=0;
void test01(){
Person p;//
空对象占用的内存空间为1
//因为C++会给每个空对象也会分配一个字节空间,为例区分空对象占内存的位置
//每个空对象也应该有一个独一无二的内存地址,因此需要一个字节的内存
cout<<"sizeof p="<<sizeof(p)<<endl;
}
void test02(){
Person p;//
cout<<"sizeof p="<<sizeof(p)<<endl;
}
int main(){
test01();
test02();
}
2.this指针概念
C++通过提供特殊的对象指针(this指针),this指针指向调用的成员所属的对象
this指针隐含在每一个非静态成员函数内
this指针不需要定义,直接使用即可
this指针的用途:
- 当形参和成员变量同名时,可用this指针来区分
- 在类的非静态成员函数中返回对象本身,可使用return*this
class Person{
public:
Person(int age){
this->age=age;
this指针指向的是被调用的成员函数所属的对象
Person& PersonAddAge(Person &p){//这个时候返回值类型要用引用的形式
this->age+=p.age;
return *this://this是指向p2的指针,*this就是p2本身
}
}
int age;//被调用的成员函数
};
1.解决命名冲突
void test01(){
Person p1(18);
cout<<"p1的年龄为:"<<p1.age<<endl;
}
2.返回对象本身用*this
void test01(){
Person p1(10);
Person p2(20);
p2.PersonAddAge(p1).PersonAddAge(p1).PersonAddAge(p1);//链式编程思想C
cout<<"p2的年龄为"<<p2.age<<endl;
}
int main(){
test01();
}
3.空指针访问成员函数
C++中空指针也可以调用成员函数,但是要注意有没有用到this指针
如果用到this指针,需要加以判断来保证代码的健壮性
class Person{
public:
void showCLassName(){
cout<<"this is Person class"<<endl;
}
void showPersonAge(){
if(this==NULL){return;}
cout<<"age="<<this->m_Age<<endl;//报错原因为传入的指针为NULL
}
int m_Age;
};
void test01(){
Person *p;=NULL;
p->showClassName;
p->showPersonAge;//这行会报错
}
int main(){
test01();
}
4.const修饰成员函数
常函数:
- 成员函数后加const修饰后,我们称这个函数为常函数
- 常函数内不可以修改成员属性
- 成员属性声明时加关键字mutable后,在常函数中依然可以修改
常对象:
- 声明对象前加const称该对象为常对象
- 常对象只能调用常函数
class Person{
public:
//this指针的本质是指针常量,指针的指向是不可修改的
//Person *const this;
//在成员函数后边加const,修饰的是this指向,让指针指向的值也不可以修改
void showPerson() const{
//this->m_A=100;//不可修改
this->m_B=100;//可以修改
//this->NULL;
}
void func(){}
int m_A;
mutable int m_B;//特殊变量,即使在常函数中也可以修改这个值
};
void test01(){
Person p;
p.showPerson();
}
void test02(){
const Person p;//在对象前加const变成常对象
//p.m_A=100;//不可修改
p.m_B=100;//m_B是特殊值,在常对象下也可以修改
常对象只能调用常函数
p.showPerson();
//p.func();//不可以调用
//常对象不可以调用普通成员函数,因为普通成员函数可以修改属性
}
int main(){
test01();
test02();
}