《C++学习》对象模型和this指针
一、成员变量和成员函数分开存储
只有非静态成员变量才属于类的对象
#include<iostream>
using namespace std;
class Person {
int m_A;//非静态成员变量,属于类的对象上
static int m_B;//静态成员变量,不属于类的对象上
void func();//不属于类的对象上
static void func2();//不属于类的对象上
};
void test01() {
Person p;
//空对象占用的内存空间是1
//C++编译器会给每一个对象也分配一个字节空间,是为了区分空对象占内存的位置
//每个空对象也需要有一个独一无二的内存地址,所以都要分配字节
cout << "size of p=" << sizeof(p) << endl;
}
void test02() {
Person p;
cout << "size of p=" << sizeof(p) << endl;
}
int main() {
test02();
return 0;
}
这里面有两个知识点,一个是空对象占用1个内存空间,第二个是只有非静态成员变量才属于类的对象,所以可以知道test02的结果一直都是4
二、this指针
this指针指向被调用的成员函数所属的对象,是隐含每一个非静态成员函数内的一种指针,不需要被定义,直接用就可以了
1、用途
(1)当形参和成员变量同名时,可以用this指针来区分
(2)在类的非静态成员函数中返回对象本身,可使用return*this
#include<iostream>
using namespace std;
class Person {
public:
Person(int age) {
this->age = age;
}
int age;
Person &PersonAddAge(Person& p) {
this->age += p.age;
//this指向p2的指针,但是*this指向的是p2的本体
return *this;
}
};
//1.解决名称冲突
void test01() {
Person p1(18);
cout << "p1的年龄是:" << p1.age << endl;
}
//2.返回对象本身用*this
void test02() {
Person p1(10);
Person p2(10);
//链式编程思想
p2.PersonAddAge(p1).PersonAddAge(p1).PersonAddAge(p1);//答案是40
}
解释代码:对于返回对象本身用*this,是可以反复调用同一个函数,从而达到不同增加的一个效果,是一种链式编程思想
2、空指针访问成员函数
C++中空指针也可以调用成员函数的,但是也要注意有没有用到this指针,如果用到了this指针,需要加以判断保证代码的健壮性
#include<iostream>
using namespace std;
class Person {
public:
//没有this的可以正常使用
void showClassName() {
cout << "name" << endl;
}
//报错原因,一般在属性前都默认加了this->,
// 而传进来的是一个空指针,要一个空指针去访问一个属性会报错
void showClassAge() {
//解决问题
if (this != NULL) {
return;
}
cout << "age=" << this->age << endl;
}
int age;
};
void test() {
Person* p = NULL;
p->showClassName();
p->showClassAge();
}
int main() {
test();
return 0;
}
三、const修饰成员函数
常函数:
(1)成员函数后加const后我们称这个函数为常函数
(2)常函数内不可以修改成员属性
(3)成员属性声明时加关键字mutable后,在常函数中依然可以修改
常对象:
(1)声明对象前加const称该对象为常对象
(2)常对象只能调用常函数
#include<iostream>
using namespace std;
class Person {
public:
//this指针的本质是指针常量,指针的指向是不可以修改的
//在成员函数后面加const,相当于const show * const this,
// 修饰的是this指针,让指针指向的值也不可以修改
void show() const {
this = NULL;//会报错,this指针不可以修改指针的指向
this->m_A = 100;//会报错,因为常函数不能修改属性
this->m_B = 100;//不会报错,加了mutable
}
void func() {
}
int m_A;
mutable int m_B;
};
void test01() {
Person p;
p.show();//普通对象可以调用常函数
}
void test02() {
const Person p;
p.m_A = 100;//报错
p.m_B = 100;
p.show();
p.func();//报错
}
知识点:
(1)普通对象可以调用普通函数和常函数
(2)常对象只能调用常函数