C++——this关键字和new关键字
一、this
关键字
1. 什么是 this
?
this
是 C++ 中的一个隐式指针,它指向当前对象(即调用成员函数的对象),在成员函数内部使用,用于引用调用该函数的对象。每个类的非静态成员函数内部都可以使用 this
。
使用 this 可以明确指出成员函数正在操作的是哪个对象的数据成员。
2. 为什么需要 this
?
当成员函数的参数名与成员变量名相同时,可以用 this
来区分。
示例代码:
#include <iostream>
using namespace std;class Person {
private:string name;int age;public:// 构造函数,参数名与成员变量名相同Person(string name, int age) {this->name = name; // 用 this 区分成员变量和参数this->age = age;}void printInfo() {// this 可以省略,但显式使用更清晰cout << "Name: " << this->name << ", Age: " << this->age << endl;}// 返回当前对象的引用(用于链式调用)Person& setName(string name) {this->name = name;return *this; // 返回当前对象本身}
};int main() {Person p("Alice", 25);p.printInfo(); // 输出: Name: Alice, Age: 25// 链式调用p.setName("Bob").printInfo(); // 输出: Name: Bob, Age: 25return 0;
}
代码解释:
- 在构造函数中,参数名
name
和age
与成员变量同名,用this->name
表示成员变量。 printInfo()
中this
可以省略,但显式使用让代码更清晰。setName()
返回*this
(即当前对象的引用),支持链式调用。
3. this
的其他用途
- 传递当前对象给其他函数
- 在成员函数中返回当前对象本身
- 解决局部变量与成员变量同名的问题
示例:
class Example {int value;
public:Example(int value) {this->value = value; // 区分成员变量和参数}void show() {cout << "Value: " << value << endl; // 等价于 this->value}Example& increment() {this->value++; // 修改当前对象的成员return *this; // 返回当前对象本身}
};
4. this
的注意事项
this
是指针,不是引用(*this
才是当前对象的引用)- 静态成员函数中没有
this
(因为静态函数不属于任何对象) - 不要随意返回
this
的指针(可能导致悬空指针)
二、new
关键字
1. 什么是 new
?
new
是 C++ 中用于动态内存分配的运算符,它在堆(heap)上创建对象并返回指针。
2. 为什么需要 new
?
- 在程序运行时(而非编译时)决定内存分配
- 创建的对象生命周期不受作用域限制
- 可以创建大型对象(栈空间可能不足)
3. 基本用法
示例代码:
#include <iostream>
using namespace std;class Dog {string name;int age;
public:Dog(string n, int a) : name(n), age(a) {}void bark() {cout << name << " says: Woof! I'm " << age << " years old." << endl;}~Dog() {cout << name << " is being destroyed." << endl;}
};int main() {// 在堆上创建 Dog 对象Dog* myDog = new Dog("Buddy", 3);myDog->bark(); // 输出: Buddy says: Woof! I'm 3 years old.// 必须手动释放内存delete myDog; // 输出: Buddy is being destroyed.return 0;
}
代码解释:
new Dog("Buddy", 3)
在堆上创建对象,返回指向它的指针。- 通过指针访问成员用
->
运算符。 delete
释放内存并调用析构函数。
4. new
的高级用法
动态数组分配:
int main() {// 动态分配包含 5 个 int 的数组int* arr = new int[5];for (int i = 0; i < 5; i++) {arr[i] = i * 10; // 赋值}for (int i = 0; i < 5; i++) {cout << arr[i] << " "; // 输出: 0 10 20 30 40}cout << endl;// 释放数组要用 delete[]delete[] arr;return 0;
}
注意事项:
- 数组必须用
delete[]
释放,单个对象用delete
。 - 忘记释放会导致内存泄漏。
5. new
的替代方案(现代 C++)
使用智能指针(推荐):
#include <memory>int main() {// 自动管理内存的 unique_ptrunique_ptr<Dog> smartDog(new Dog("Max", 4));smartDog->bark();// 不需要手动 delete,离开作用域自动释放// 更安全的 make_unique (C++14)auto smartDog2 = make_unique<Dog>("Charlie", 5);smartDog2->bark();return 0;
}
6. new
的注意事项
必须配对使用
delete
:
int* p = new int; // 分配
*p = 10;
delete p; // 释放
- 避免内存泄漏:
void leakyFunction() {int* leak = new int[100]; // 分配但未释放// 如果中间发生异常,delete 永远不会执行
} // 内存泄漏!
- 不要重复释放:
int* p = new int;
delete p; // 正确
delete p; // 错误!未定义行为
检查分配是否成功(现代 C++ 中
new
失败会抛出std::bad_alloc
异常)初始化分配的内存:
// C++11 统一初始化
int* p1 = new int{42}; // 值初始化为 42// 默认初始化(值不确定)
int* p2 = new int;// 动态数组初始化为 0
int* arr = new int[10](); // 所有元素初始化为 0
三、总结对比
特性 | this 关键字 | new 运算符 |
---|---|---|
作用 | 指向当前对象 | 动态分配内存 |
返回值 | 当前对象的指针 | 新分配内存的指针 |
使用场景 | 成员函数中访问当前对象 | 需要运行时决定内存分配时 |
内存位置 | 不适用(是指针) | 堆(heap) |
生命周期 | 不适用 | 直到显式 delete 或程序结束 |
错误风险 | 误用可能导致逻辑错误 | 忘记释放导致内存泄漏 |
最佳实践建议:
this
使用建议:- 在成员变量和参数同名时使用
- 需要返回当前对象时(链式调用)
- 避免过度使用,保持代码清晰
new
使用建议:- 优先考虑栈分配或智能指针
- 如果必须用
new
,确保有对应的delete
- 对于数组,使用
std::vector
代替new[]
- 在 C++11+ 中,优先使用
std::make_unique
/std::make_shared
- 现代 C++ 趋势:
- 减少裸
new
/delete
的使用 - 使用 RAII(资源获取即初始化)原则
- 依赖标准库容器和智能指针管理资源
- 减少裸