一、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(资源获取即初始化)原则
- 依赖标准库容器和智能指针管理资源
- 减少裸