三、c++对象模型和this指针
1、成员变量和成员函数分开存储
![]()
#include <iostream>
#include <string>
using namespace std;
//成员变量和成员函数分开存储
//只有非静态成员变量,属于类的对象上
class Person {
int m_A; //非静态成员变量,属于类的对象上
static int m_B; //静态成员变量,不属于类的对象上
void func() {} //非静态成员函数,和成员变量分开存储,,不属于类的对象上
static void func2() {} //静态成员函数,不属于类的对象上
};
int Person::m_B = 0;
void test01() {
Person p;
//空对象占用内存空间:1
//C++编译器会给每个空对象分配一个字节空间,是为了区分空对象占用内存的位置
//每个空对象都应该有一个独一无二的内存地址
cout << "sizeof(p) = " << sizeof(p) << endl;
}
void test02() {
//p象占用内存空间:4
Person p;
cout << "sizeof(p) = " << sizeof(p) << endl;
}
int main() {
//test01();
test02();
system("pause");
return 0;
}
2、this指针概念
![]()
#include <iostream>
#include <string>
using namespace std;
//this
//1.解决名称冲突
//2.返回对象本身
class Person {
public:
Person(int age) {
//age = age; //此地的age 和属性age没有关系
//this 指针指向的是被调用的成员函数 所属的对象
this->age = age;
}
/*
如果这里是Person 的返回类型
相当于用值的方式返回局部的对象,调用拷贝构造函数,复制了一份新的数据出来。
第一次调用后,按照p2的本体创造了一个新的数据。
若以引用的方式返回,则返回本体。
*/
Person &PersonAddAge(Person &p) {
this->age += p.age;
//this 指向p2的指针,而*this指向的就是p2这个对象的本体
return *this;
}
int age;
};
//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);
cout << "P2的年龄:" << p2.age << endl;
}
int main() {
test01();
test02();
system("pause");
return 0;
}
3、空指针访问成员函数
![]()
#include <iostream>
#include <string>
using namespace std;
//空指针调用成员函数
class Person {
public:
void showClassName() {
cout << " this is Person class " << endl;
}
void showPersonAge() {
//此处引发了异常,属性 m_Age 前都默认加了this->m_Age;
//指针this指向的Person是一个空指针,没有指向确切的数据
//空的值访问属性,是不可能的
//报错原因是访问传入的指针式NULL
//cout << "age = " << m_Age << endl;
if (this == NULL) {
return;
}
cout << "age = " << this->m_Age << endl;
}
int m_Age;
};
void test01() {
Person * p = NULL;
p->showClassName();
p->showPersonAge();
}
int main() {
test01();
system("pause");
return 0;
}
4、const修饰成员函数
![]()
#include <iostream>
#include <string>
using namespace std;
//常函数:成员函数后加const
//常对象:对象前加const
class Person {
public:
//this指针的本质是指针常量:指针的指向式不可以修改的
//Person * const this; 指针指向的值不可以修改
//const Person * const this; 指针指向和指针指向的内容都不可修改
//在成员函数后面加const本质是修饰的this
void showPerson() const {
//this->m_A = 100; //常函数的原因
//this = NULL; //this指针本身不可以修改指针的指向的
this->m_B = 100;
}
void func() {
m_A = 100;
}
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;
//常对象只能调用常函数
p.showPerson();
//常对象不可以调用普通成员函数,因为普通成员函数可以修改属性
//而常对象本身不允许修改属性,两者相违背。故错误
//p.func();
}
int main() {
test01();
system("pause");
return 0;
}