1. this指针:对象自引用的核心机制

在C++中,​this指针是一个特殊的指针,它指向调用当前成员函数的对象实例。this指针是每个非静态成员函数的隐含参数,由编译器自动生成并传递,使得成员函数能够访问该对象的成员变量和方法

1.1 this指针的基本特性

  • 隐含指针​:编译器会在每个非静态成员函数的参数列表中隐式添加一个this指针参数。
  • 类型​:this指针的类型是ClassName* const(指向类对象的常量指针),在const成员函数中则为const ClassName* const(指向常量对象的常量指针)。
  • 不可修改性​:this指针本身是一个常量指针,其指向不能改变。

1.2 this指针的主要用途

  • 解决命名冲突​:当成员变量与函数参数同名时,使用this->member明确指定成员变量。
class Hero {
public:
    Hero(int hp) {
        this->hp = hp; // 使用this区分成员变量和参数
    }
private:
    int hp;
};
  • 实现链式调用​:通过返回*this(当前对象的引用),支持连续调用同一对象的多个方法。
class Counter {
public:
    Counter& increment() {
        count++;
        return *this; // 返回当前对象的引用
    }
};
  • 返回当前对象或传递对象​:在成员函数中返回指向当前对象的指针或将当前对象传递给外部函数。

2. const修饰成员函数:保证对象状态不被修改

2.1 常函数(Const Member Functions)

在成员函数声明后加上const关键字,该函数称为常函数。常函数内不能修改类的非mutable成员变量

class Hero {
public:
    int getHp() const { // const成员函数
        // hp = hp + 1; // 错误:不能修改成员变量
        return hp;
    }
private:
    int hp;
};

2.2 常函数中的this指针

在常函数中,this指针的类型变为const ClassName* const,这意味着不能通过this指针修改对象的状态(除非成员被声明为mutable)

2.3 常对象(Const Objects)

const修饰的对象称为常对象,只能调用const成员函数

int main() {
    const Hero h; // 常对象
    h.getHp();    // 正确:getHp()是const成员函数
    // h.setHp(100); // 错误:setHp()不是const成员函数
    return 0;
}

3. mutable关键字:突破const限制的灵活工具

3.1 mutable的作用

mutable关键字用于修饰类的成员变量,允许在const成员函数中修改被修饰的变量,打破了"const成员函数不能修改成员变量"的限制

3.2 典型使用场景

  • 缓存数据​:存储计算结果,避免重复计算。
  • 计数器​:记录函数调用次数等统计信息。
  • 线程同步​:在const成员函数中使用互斥锁(锁的状态变化不影响对象逻辑状态)。
class Hero {
public:
    int getHp() const {
        _hpCount++; // mutable变量可在const函数中修改
        return _hp;
    }
private:
    int _hp;
    mutable int _hpCount; // 使用mutable修饰
};

3.3 注意事项

  • 谨慎使用​:mutable应仅用于不影响对象逻辑状态的辅助变量,滥用会破坏const语义。
  • 不能修饰静态成员​:mutable只能修饰非静态成员变量。

4. 综合应用与总结

4.1 三者关系示意图

+----------------+      +-----------------+      +-----------------+
|   this指针     |      | const成员函数   |      |   mutable变量   |
|                |      |                 |      |                 |
| - 指向当前对象 |      | - 保护对象状态  |      | - 突破const限制 |
| - 支持链式调用 |      | - 限制修改操作  |      | - 记录内部状态  |
+----------------+      +-----------------+      +-----------------+
         |                        |                          |
         +------------------------+--------------------------+
                                  |
                         +-----------------+
                         |   对象完整性    |
                         +-----------------+

4.2 关键区别与联系

特性 this指针 const成员函数 mutable关键字
基本作用 对象自引用 保护对象状态 突破const限制
使用场景 所有非静态成员函数 不修改对象状态的函数 需要修改的内部状态变量
const影响 在const函数中类型变化 禁止修改非mutable成员 允许在const函数中修改
对象内存 不增加对象大小 不增加对象大小 增加对象大小

4.3 最佳实践建议

  1. 合理使用this​:在命名冲突或需要链式调用时显式使用this指针,提高代码可读性。
  2. 正确使用const​:任何不会修改数据成员的函数都应该声明为const类型,增强代码安全性和可维护性。
  3. 审慎使用mutable​:仅当修改的变量不影响对象逻辑状态时才使用mutable,避免破坏const语义。
  4. 注意空指针风险​:通过空指针调用成员函数会导致未定义行为,需确保对象有效。

理解并合理运用this指针、const成员函数和mutable关键字,能够编写出更加安全、灵活和高效的C++代码,同时提升程序的健壮性和可维护性。

源码区:

this指针:

#include<iostream>
#include<string>
using namespace std;
/*
this指针
解决命名冲突
*this可以获得这个对象本身
*/
class Hero
{
public:
	Hero(int hp) {
	/*hp = hp;*///形参赋值给了自己,无意义,命名冲突了
		this->hp = hp;//获取了成员变量
		cout << this << endl;//this本质是指针指向对象h
		cout << (*this).hp << endl;//*this=对象h
	}
	~Hero(){}
	int hp;
};
int main()
{
	Hero h(10);
	cout << h.hp << endl;
	cout << &h << endl;//打印对象地址
	cout << (*(&h)).hp << endl;//(*(&h))等于对象h。
	return 0;
}

const常量修饰函数:

#include<iostream>
#include<string>
using namespace std;
/*
const 修饰成员函数
*/

//常函数 无法修改函数成员变量的值,保护函数的安全
class hero {
public :
	hero():hp(0) {};
	int gethp()const//加了以后函数内部的hp就不能修改了
	{

		/*hp = hp + 1;*///会报错
		return hp;
	}
	int sethp(int hp)
	{
		this->hp = hp;
	}
private:
	int hp;

};

int main()
{
	const hero h;//常量对象,对象无法被修改
	/*h(100);*///因为是常量变量所以无法改变成员变量,会修改对象的值而对象是常量所以冲突
	return 0;
}

mutable关键字:

#include<iostream>
#include<string>
using namespace std;

//mutable<-->const//是相对的
class hero
{
public:hero():_hp(0),_hpcount(0){}
	int gethp()const
	{
		_hpcount++;//无法修改,但是加了mutable以后就可以修改了,不会报错
		return _hp;
	}
	void printcount()
	{
		cout << "count=" << _hpcount << endl;
	}

private:
	int _hp;
mutable	int _hpcount;

};
int main()
{
	hero h;
	h.gethp(); h.gethp(); h.gethp(); h.gethp(); h.gethp(); h.gethp();
	h.printcount();//调用函数输出是6

	return 0;
}

Logo

Agent 垂直技术社区,欢迎活跃、内容共建。

更多推荐