cpp自学 day15(类和对象——对象模型和this指针)

成员变量和成员函数分开存储

只有非静态成员属于对象

class person 
{
   };

void test01()
{
    Person p;
   
    cout << "size of p = " << sizeof(p) << endl;
};

 1、空对象占用内存空间为:1
 2、C++编译器会给每个空对象也分配一个字节空间,是为了区分空对象占内存的位置
 3、每个空对象也应该有一个独一无二的内存地址

class Person
{
    int m_A;         非静态成员变量 属于类的对象上
    
    static int m_B;  静态成员变量 不属于类对象上

    void func() {}   非静态成员函数 不属于类对象上

    static void func2() {}  静态成员函数 不属于类的对象上
}

void test01()
{
    Person p;
   
    cout << "size of p = " << sizeof(p) << endl;
};
  输出结果为4个字节,对应int m_A

至于为什么不是1+4=5个字节大小,这关于内存对齐,后续会学。

this指针概念

成员变量成员函数是分开存储的,每一个非静态成员函数只会诞生一份函数实例,也就是说多个同类型的对象会共用一块代码。

那么问题是:这一块代码是如何区分哪个对象调用自己的呢?

C++通过提供特殊的对象指针,this指针,解决上述问题。

this指针指向被调用的成员函数所属的对象。

this指针是隐含每一个非静态成员函数内的一种指针。

this指针不需要定义,直接使用即可。

this指针的用途

解决名称冲突

- 当形参和成员变量同名时,可用this指针来区分

class Person
{
public:
    Person(int age)
    {
        this->age = age;(√)  this指针指向被调用的成员函数所属的对象。
              age = age;(×)  
    }

    int age;         
};                             这里this就指向有参构造函数Person()所属的对象p1

void test01()
{
    Person p1(18);
    cout << "p1的年龄为:" << p1.age << endl;
}

- 在类的非静态成员函数中返回对象本身,可使用return *this

class Person
{
public:
    Person(int age)
    {
        this->age = age;(√)  
              age = age;(×)  
    }

    Person& PersonAddAge(Person &p) 引用方式返回对象,不会复制创建新的对象,若用
    {                               若用值的方式返回,则会创建一个p2',再调用又会创建p2'' 
    this->age += p.age;

    //this指向p2的指针,而*this指向的就是p2这个对象本体
    return *this;
    }

    int age;                   this指针指向被调用的成员函数所属的对象。
};                             这里this就指向有参构造函数Person()所属的对象p1

void test02()
{
    年龄相加
    Person p1(10);
    Person p2(10);

    链式编程思想   若要像这样连续调用,则我们需要返回p2
    p2.PersonaAddAge(p1).PersonaAddAge(p1).PersonaAddAge(p1);

                               若用值的方式返回,则会创建一个p2',再调用又会创建p2''

    cout << "p2的年龄为:" << p2.age << endl;
}

空指针访问成员函数

C++中空指针也是可以调用成员函数的,但是也要注意有没有用到this指针。

如果用到this指针,需要加以判断保证代码的健壮性

if (this == null) {
   return;
}                   可通过这段代码防止空指针访问成员函数报错
  • 如果成员函数中使用了this指针,而this指针是空的,那么程序将表现出未定义行为。未定义行为可能导致程序崩溃、数据损坏或其他不可预测的结果。

  • this指针用于访问对象的成员变量和调用其他成员函数。如果this指针为空,任何试图通过它访问成员的操作都会导致访问违规(Access Violation),从而导致程序崩溃。、

const修饰成员函数

常函数


- 成员函数后加const后我们称为这个函数为常函数
- 常函数内不可以修改成员属性
- 成员属性声明时加关键字mutable后,在常函数中依然可以修改

class Person{

this指针的本质 是指针常量 指针的指向是不可以修改的

在成员函数后面加const,修饰的是this指向,让指针指向的值也不可以修改

则此时的形式为 const Person * const this;

void showPerson() const
{
    this->m_B = 100;
    //this->m_A = 100;
    //this = NULL; //this指针不可以修改指针的指向的
}

int m_A;
mutable int m_B; 
                特殊变量,即使在常函数中,也可以修改这个值,加关键字mutable
}

void test01()
{
    Person p;
    p.showPerson();
}

常对象


- 声明对象前加const称该对象为常对象
- 常对象只能调用常函数

常对象
void test02()
{
    const Person p;       在对象前加const,变为常对象
    //p.m_A = 100;
    p.m_B = 100;          m_B是特殊值,在常对象下也可以修改
}
p.func();   常对象 不可以调用普通成员函数,因为普通成员函数可以修改属性

AI整理后的C++核心概念笔记 (成员变量、this指针、常函数)


一、成员变量与成员函数存储规则
类型存储位置是否属于对象示例
非静态成员变量对象内存中✔️int m_A;
静态成员变量全局数据区static int m_B;
非静态成员函数代码区void func() {}
静态成员函数代码区static void func2() {}

关键结论

  • 空对象默认占 ​1字节​(确保对象有唯一地址)。
  • 对象大小 = 非静态成员变量总大小(内存对齐后)。
class Person {}; // sizeof(Person) = 1
class Person { int m_A; }; // sizeof(Person) = 4

二、this指针核心机制
1. ​本质与特性
  • 隐含指针:每个非静态成员函数自动包含 Person* const this(指针常量,指向不可变)。
  • 用途
    • 解决名称冲突:区分成员变量与形参。
    • 链式调用:返回对象本体(return *this;)。
2. ​代码示例
// 解决名称冲突
Person(int age) {
    this->age = age; // ✅ 明确指向成员变量
}

// 链式调用
Person& PersonAddAge(Person& p) {
    this->age += p.age;
    return *this; // 返回对象本体(而非副本)
}

// 使用
Person p2(10);
p2.PersonAddAge(p1).PersonAddAge(p1); // p2.age累加两次
3. ​空指针访问成员函数
  • 风险:空指针调用依赖this的函数会导致崩溃。
  • 防护:增加空指针检查。
void printAge() {
    if (this == nullptr) return; // ✅ 健壮性检查
    cout << this->age; 
}

三、const修饰成员函数(常函数)
1. ​规则与特性
类型语法this指针形式能否修改成员变量
普通函数void func() {...}Person* const this✔️
常函数void func() constconst Person* const this❌(除非变量用mutable
2. ​代码示例
class Person {
public:
    void show() const { // 常函数
        // this->m_A = 100; ❌ 编译错误
        this->m_B = 100; // ✅ mutable变量允许修改
    }
    int m_A;
    mutable int m_B; 
};

// 常对象
const Person p;
// p.m_A = 200; ❌ 常对象禁止修改普通成员
p.m_B = 200; // ✅ 允许修改mutable成员
3. ​重要规则
  • 常对象只能调用 ​常函数​(普通函数可能修改成员,违反const语义)。
const Person p;
p.show(); // ✅ 常对象调用常函数
// p.func(); ❌ 禁止调用普通函数

四、核心概念总结
概念核心要点
空对象内存占1字节,保证对象有唯一地址。
this指针隐含指针,指向调用者对象;支持链式编程和解决命名冲突。
常函数const修饰,禁止修改成员变量(mutable例外)。
常对象const修饰,只能调用常函数,禁止修改非mutable成员。

关联记忆
this-> 明确指向 → 常函数锁成员 → 常对象限调用 → mutable破约束。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值