this指针
在c++类中默认含有this指针,并且在主函数调用实参时不能被写出,c++是不允许的
cpp
class date//定义类=struct
{
public://公开
void Init(int year, int month, int day)//日期类的初始化
{
_year = year;
_month = month;
_day = day;
}
void print(int year,int month,int day)
{
cout << year << "/" << month << "/" << day << endl;
}
private://私人
int _year;//成员变量
int _month;
int _day;
};//分号不能省略
int main()
{
date a;
date b;
a.Init(2026,7,12);
a.print(2026,7,12);
b.Init(2026,3,12);
b.print(2026,3,12);
//共用一个函数,但是打印的结果不同,这是为什么?
return 0;
当然我们也可以这样写:
cpp
#include<iostream>
using namespace std;
class date//定义类=struct
{
public://公开
void Init(int year, int month, int day)//日期类的初始化
{
this->_year = year;
this->_month = month;
this->_day = day;
}
//void print(date*const this)//隐式,不能写
void print()
{
cout << this->_year << "/" << this->_month << "/" << this->_day << endl;
}
private://私人
int _year;//成员变量
int _month;
int _day;
};//分号不能省略
int main()
{
date a;
date b;
a.Init(2026,7,12);
a.print();
b.Init(2026,3,12);
b.print();
//共用一个函数,但是打印的结果不同,这是为什么?
return 0;
}

小练习:this指针是放在哪里的: 一般放在栈
private:中的成员只是声明,没有开空间,必须要等到对象实例化才行
重载operator
1. 运算符重载的基本概念
运算符重载的本质是函数重载。当我们使用一个运算符(如+, -, ==)时,编译器会将其转换为对特定运算符函数的调用。对于自定义类型,我们可以自己定义这个函数。
重载规则与限制:
- 可重载的运算符 :大部分C++运算符都可以重载,例如算术运算符(
+,-,*,/)、关系运算符(==,!=,<,>)、逻辑运算符(&&,||)、赋值运算符(=)、下标运算符([])、函数调用运算符(())等。 - 不可重载的运算符 :成员访问运算符(
.)、成员指针运算符(.*)、作用域解析运算符(::)、条件运算符(?:)、sizeof运算符以及typeid运算符。 - 操作数数量:重载后的运算符必须保持其原有的操作数数量(一元或二元)。
- 至少一个操作数为用户自定义类型:不能为两个内置类型重载一个新的运算符。
2. 运算符重载的语法
运算符重载函数可以是类的成员函数 ,也可以是非成员函数(通常是友元函数)。
2.1 作为成员函数重载
当运算符重载为类的成员函数时,它的第一个(对于二元运算符)或唯一一个(对于一元运算符)操作数隐式地是调用该函数的对象本身(即*this)。
语法格式:
cpp
返回类型 operator运算符符号 (参数列表) {
// 函数体
}
示例:重载+运算符实现两个Date对象的日期相加(按天数)
cpp
class Date {
public:
Date(int year = 1970, int month = 1, int day = 1)
: _year(year), _month(month), _day(day) {}
// 成员函数重载 + 运算符
Date operator+(int days) const {
Date temp(*this); // 创建当前对象的副本
temp._day += days;
// 这里应添加处理月份和年份进位的逻辑,为简化示例省略
// 例如,当temp._day大于当月天数时,月份+1,天数重置
return temp; // 返回新对象,不改变原对象
}
void Print() const {
cout << _year << "/" << _month << "/" << _day << endl;
}
private:
int _year;
int _month;
int _day;
};
int main() {
Date d1(2026, 7, 23);
Date d2 = d1 + 5; // 等价于 d1.operator+(5)
d2.Print(); // 输出:2026/7/28 (假设)
return 0;
}
2.2 作为非成员函数(友元)重载
有些运算符,如输入输出运算符(<<, >>),其左侧操作数是流对象(ostream/istream),而不是自定义类的对象,因此必须定义为非成员函数。为了能访问类的私有成员,通常将其声明为类的friend(友元)。
示例:重载<<运算符方便输出
cpp
#include <iostream>
using namespace std;
class Date {
// 声明友元函数
friend ostream& operator<<(ostream& out, const Date& d);
public:
Date(int year = 1970, int month = 1, int day = 1)
: _year(year), _month(month), _day(day) {}
private:
int _year;
int _month;
int _day;
};
// 定义全局的 operator<< 函数
ostream& operator<<(ostream& out, const Date& d) {
out << d._year << "/" << d._month << "/" << d._day;
return out; // 支持链式调用,如 cout << d1 << " " << d2;
}
int main() {
Date d(2026, 7, 23);
cout << "Today is: " << d << endl; // 直接使用 << 输出Date对象
return 0;
}
3. 特殊运算符重载示例
3.1 前置++与后置++
为了区分前置和后置递增,C++规定后置版本接受一个额外的int类型参数(该参数无实际意义,仅用于区分)。
cpp
class Counter {
public:
Counter(int val = 0) : value(val) {}
// 前置++:返回递增后的对象的引用
Counter& operator++() {
++value;
return *this;
}
// 后置++:参数int仅用于区分,返回递增前的对象副本
Counter operator++(int) {
Counter temp = *this;
++value; // 或者 ++(*this)
return temp;
}
int getValue() const { return value; }
private:
int value;
};
int main() {
Counter c(5);
Counter a = ++c; // 前置:c先加1,再赋值给a
cout << "a: " << a.getValue() << ", c: " << c.getValue() << endl; // a:6, c:6
Counter b = c++; // 后置:c先赋值给b,再加1
cout << "b: " << b.getValue() << ", c: " << c.getValue() << endl; // b:6, c:7
return 0;
}
3.2 赋值运算符=
赋值运算符通常需要深拷贝,并处理自赋值情况。它应返回对象的引用以支持链式赋值(a = b = c)。
cpp
class MyString {
public:
MyString(const char* str = nullptr) {
if (str) {
data = new char[strlen(str) + 1];
strcpy(data, str);
} else {
data = new char[1];
*data = '\0';
}
}
// 拷贝构造函数(略)
// 析构函数(略)
// 重载赋值运算符
MyString& operator=(const MyString& other) {
if (this != &other) { // 1. 检查自赋值
delete[] data; // 2. 释放原有资源
data = new char[strlen(other.data) + 1]; // 3. 申请新资源
strcpy(data, other.data); // 4. 拷贝数据
}
return *this; // 5. 返回自身引用
}
private:
char* data;
};
4. 习题解析与常见问题
习题总结:

x的值不变,因为x被const修饰,operator++函数不能改变const对象的值。
运算符重载问题:

该图可能展示了关于运算符重载优先级、结合性或定义冲突的典型问题。例如,重载&&和||会失去短路求值特性;重载逗号运算符,可能改变求值顺序。在设计重载时,应尽量保持运算符的原始语义,避免造成使用者的困惑。
5. 总结
- 前置
++:Counter& operator++();返回引用,效率高。 - 后置
++:Counter operator++(int);返回副本,参数int为占位符。 ++是单目运算符,所以作为成员函数重载时没有显式参数(后置的int除外)。