在上一篇文章中,我们已经初步认识了类和对象的基本概念。今天,我们将深入探讨 C++ 中一个非常关键且容易混淆的概念------this 指针。理解 this 指针,是掌握类成员函数内部工作机制的重要一步。本文将通过一个具体的 Date 类示例,带你直观地理解 this 指针的来龙去脉。
this指针
我们先来看一个类:
cpp
#include<iostream>
using namespace std;
class Date
{
public:
void Init(int year, int month, int day)
{
_year = year;
_month = month;
_day = day;
}
void Print()
{
cout << _year << '/' << _month << '/' << _day << endl;
}
private:
int _year;
int _month;
int _day;
};
在类Date中有两个函数Init和Print,我们创建Date类的两个对象,比如d1和d2,这两个对象都要访问这些成员函数,那么它们是如何准确地找到并访问到自己对象中的内容的呢?
cpp
int main()
{
Date d1, d2;
d1.Init(2026, 9, 11);
d2.Init(2026, 10, 1);
d1.Print();//打印d1中的日期
d2.Print();//打印d2中的日期
return 0;
}

在编译时,编译器会为每个成员函数的参数部隐式地添加一个 this 指针,该指针在参数列表第一个位置,为类类型,且const修饰放在 * 右边,以防修改指针指向,所以成员函数的参数列表实际上是这样的:
cpp
void Init(int year, int month, int day,Date* const this)
而我们传过去的参数会隐式地多一个,是对象的地址。
cpp
d1.Init(&d1);
该 this 指针用于接收对象地址,然后去访问对象内部的成员变量,所以成员函数实际上是这样的:
cpp
void Init(int year, int month, int day,Date* const this)
{
this->_year = year;
this->_month = month;
this->_day = day;
}
编译器不允许我们显示地在形参和实参部分写this指针,但允许在成员函数内部使用。
cpp
void Print()
{
cout << this->_year << '/' << _month << '/' << this->_day << endl;
}
类的默认成员函数
用户没有显式实现,编译器会自动生成的成员函数称为默认成员函数。
一个类,我们不写的情况下编译器会默认生成以下6个默认成员函数,需要注意的是这6个中最重要的是前4个,最后两个取地址重载不重要,我们稍微了解一下即可。其次就是C++11以后还会增加两个默认成员函数,移动构造和移动赋值,这个我们后面再讲解。默认成员函数很重要,也比较复杂,我们要从两个方面去学习:
- 第一:我们不写时,编译器默认生成的函数行为是什么,是否满足我们的需求。
- 第二:编译器默认生成的函数不满足我们的需求,我们需要自己实现,那么如何自己实现?

构造函数
构造函数是类的一种特殊的成员函数,它的名字与类名相同,没有返回值(连 void 都不写),在对象创建时由编译器自动调用,用于完成对象的初始化工作。
以我们前面定义的 Date 类为例,如果不写构造函数,那么创建对象后成员变量 _year、_month、_day 都是未初始化的随机值,这显然是不安全的。因此我们需要自己实现一个构造函数来初始化这些成员:
cpp
class Date
{
public:
Date(int year, int month, int day)
{
_year = year;
_month = month;
_day = day;
}
private:
int _year;
int _month;
int _day;
};
有了构造函数之后,创建对象时就可以直接传入初始值:
cpp
int main()
{
Date d1(2026, 9, 11); // 调用构造函数,初始化 d1
Date d2(2026, 10, 1); // 调用构造函数,初始化 d2
return 0;
}
关于构造函数,有几点需要特别注意:
- 构造函数支持重载,即一个类可以有多个构造函数,只要参数列表不同即可。
- 构造函数可以带默认参数,方便在部分场景下省略某些实参。
- 如果用户没有显式定义任何构造函数,编译器会自动生成一个无参的默认构造函数;但一旦用户定义了构造函数,编译器就不会再自动生成了。
- 构造函数没有返回值 ,也不能写
void。 - 构造函数在对象创建时自动调用,不需要我们手动调用。
构造函数是类中最重要、最常用的默认成员函数之一,掌握好它,是写出健壮 C++ 类的基础。
我们自己写的无参构造函数、全缺省的构造函数还有编译器自动生成的都叫做默认构造函数。简单来说就是不用传参数就可以调用的构造函数。
编译器自动生成的构造函数,对于内置类型来说,一般会生成随机值;对于自定义类型则会调用对应的构造函数来初始化。
析构函数
构造函数是对实例化对象进行初始化的函数,析构函数就是用于完成对象销毁时的清理工作,在对象销毁时编译器自动调用。
析构函数与构造函数对应,它也不具有返回值(不用写void),函数名为类名前加~。
cpp
class Date
{
public:
Date(int year = 1,int month = 1,int day = 1)
{
_year =year;
_month = month;
_day = day;
}
//析构函数
~Date()
{
_year = 0;
_month = 0;
_day = 0;
}
private:
int _year;
int _month;
int _day;
};
关于析构函数需要注意的有以下几点:
- 一个类只能有一个析构函数 ,因为析构函数的作用相当于
Destory函数,完成资源清理。 - 当我们没有显示地定义析构函数时,编译器会自动生成析构函数。对于内置类型,不会做任何处理;对于自定义类型,则会调用对应的析构函数。
- 编译器自动生成的析构函数通常情况下可以满足我们的需求,除非我们手动申请开辟了一块空间,这时需要显示地定义析构函数去释放该空间。
- 后定义的对象先析构。