网站首页 > 基础教程 正文
1. 内存管理基础
JavaScript (自动垃圾回收)
// JS 自动管理堆内存
let obj = { data: 100 };
obj = null; // 对象将被 GC 回收
C (手动内存管理)
#include <stdlib.h>
void demo() {
int* arr = (int*)malloc(3 * sizeof(int)); // 堆分配
arr[0] = 10;
free(arr); // 必须手动释放
// 若忘记 free 会导致内存泄漏
}
C++ (手动 + RAII 原则)
void demo() {
int* arr = new int[3]; // 堆分配
arr[0] = 10;
delete[] arr; // 手动释放
// 更安全的做法:使用智能指针(下篇详述)
std::unique_ptr<int[]> safeArr(new int[3]);
}
JS 程序员注意:
- C/C++ 中堆内存必须手动释放(JS 无此概念)
- 忘记 delete 或 free 会导致内存泄漏
- 使用 new/delete 而非 C 的 malloc/free(避免混用)
2. 面向对象编程
JavaScript (原型链)
class JsAnimal {
constructor(name) {
this.name = name;
}
speak() {
console.log(`${this.name} makes a noise`);
}
}
class JsDog extends JsAnimal {
speak() {
super.speak();
console.log("Woof!");
}
}
const dog = new JsDog("Buddy");
dog.speak();
C (结构体 + 函数指针)
// 模拟面向对象
typedef struct {
char name[20];
void (*speak)(void* self); // 函数指针
} Animal;
void animalSpeak(void* self) {
Animal* a = (Animal*)self;
printf("%s makes a noise\n", a->name);
}
typedef struct {
Animal base;
} Dog;
void dogSpeak(void* self) {
Animal* a = (Animal*)self;
animalSpeak(self); // 类似 super 调用
printf("Woof!\n");
}
int main() {
Dog dog = { .base = { .name = "Buddy", .speak = dogSpeak } };
dog.base.speak(&dog); // 手动传递 this 指针
}
C++ (类与继承)
#include <iostream>
class Animal {
public:
Animal(const std::string& name) : name(name) {}
virtual void speak() { // 虚函数实现多态
std::cout << name << " makes a noise" << std::endl;
}
protected:
std::string name;
};
class Dog : public Animal {
public:
Dog(const std::string& name) : Animal(name) {}
void speak() override { // C++11 明确 override
Animal::speak(); // 调用父类方法
std::cout << "Woof!" << std::endl;
}
};
int main() {
Dog dog("Buddy");
dog.speak();
// 输出:
// Buddy makes a noise
// Woof!
}
核心差异:
- C++ 类有明确的访问控制(public/protected/private)
- 虚函数表(vtable)实现动态多态(JS 原型链查找类似动态绑定)
- 析构函数可手动定义资源释放逻辑(JS 无此机制)
3. 构造函数与析构函数
JavaScript (无显式析构)
class JsFile {
constructor(filename) {
this.handle = openFile(filename);
}
// 无标准析构方法,依赖 GC 回收
}
// 使用 WeakRef/FinalizationRegistry 模拟析构
const registry = new FinalizationRegistry(handle => {
closeFile(handle);
});
let obj = new JsFile("test.txt");
registry.register(obj, obj.handle);
C++ (显式生命周期控制)
class File {
public:
File(const std::string& filename) {
handle = fopen(filename.c_str(), "r");
if (!handle) throw std::runtime_error("File open failed");
}
~File() { // 析构函数确保资源释放
if (handle) fclose(handle);
}
private:
FILE* handle;
};
// 使用示例
void readFile() {
File file("test.txt"); // 构造函数调用
// 文件操作...
} // 离开作用域时析构函数自动调用
关键陷阱:
- C++ 中未正确释放资源(如文件句柄)会导致资源泄漏
- JS 依赖 GC 回收,时机不可控
4. 多态与虚函数
JavaScript (动态类型)
class Shape {
area() { throw "Not implemented"; }
}
class Circle extends Shape {
constructor(r) { super(); this.radius = r; }
area() { return Math.PI * this.radius ** 2; }
}
// 运行时多态
function printArea(shape) {
console.log(shape.area());
}
printArea(new Circle(5)); // 78.54...
C++ (虚函数表)
class Shape {
public:
virtual double area() const {
throw std::logic_error("Not implemented");
}
virtual ~Shape() = default; // 虚析构函数确保正确释放
};
class Circle : public Shape {
public:
Circle(double r) : radius(r) {}
double area() const override {
return 3.14159 * radius * radius;
}
private:
double radius;
};
void printArea(const Shape& shape) {
std::cout << shape.area() << std::endl;
}
int main() {
Circle c(5);
printArea(c); // 输出 78.5397
}
JS 程序员注意:
- C++ 必须通过虚函数 (virtual) 实现多态
- 基类析构函数应为虚函数(否则通过基类指针删除子类对象时行为未定义)
5. 运算符重载
JavaScript (无法重载运算符)
class Vector {
constructor(x, y) {
this.x = x;
this.y = y;
}
add(other) { // 手动实现加法
return new Vector(this.x + other.x, this.y + other.y);
}
}
const v1 = new Vector(1, 2);
const v2 = new Vector(3, 4);
const v3 = v1.add(v2);
C++ (运算符重载)
class Vector {
public:
Vector(double x, double y) : x(x), y(y) {}
Vector operator+(const Vector& other) const { // 重载 +
return Vector(x + other.x, y + other.y);
}
private:
double x, y;
};
int main() {
Vector v1(1, 2), v2(3, 4);
Vector v3 = v1 + v2; // 直接使用运算符
}
关键差异:
- C++ 允许重载 +, <<, == 等运算符(JS 不支持)
- 运算符重载需遵循特定语法规则(如参数数量)
6. 异常处理对比
JavaScript (动态异常)
function riskyOperation() {
throw new Error("Something went wrong");
}
try {
riskyOperation();
} catch (e) {
console.error(e.message);
}
C++ (类型安全异常)
#include <stdexcept>
void riskyOperation() {
throw std::runtime_error("Something went wrong");
}
int main() {
try {
riskyOperation();
} catch (const std::exception& e) {
std::cerr << e.what() << std::endl;
}
}
关键陷阱:
- C++ 异常需继承自 std::exception(JS 可抛出任意值)
- 栈展开时会调用局部对象的析构函数(RAII 保障资源安全)
本章小结
- 内存管理:理解堆/栈差异,掌握 new/delete 和 RAII 模式
- 面向对象:类、继承、多态的实现方式与 JS 原型链的对比
- 高级特性:运算符重载、友元函数、常量正确性
- 核心思维转变:从自动内存管理转向精确控制对象生命周期
- 上一篇: VSCode 配置 C++ 开发环境!教程详解
- 下一篇: C++异步从理论到实践总览篇
猜你喜欢
- 2025-04-26 Visual C++ 6.0软件安装包以及安装教程
- 2025-04-26 C++ Qt项目教程:WebServer网络测试工具
- 2025-04-26 C++特性使用建议
- 2025-04-26 c++11新特性总结,你都用过哪些新特性?
- 2025-04-26 十分钟搞定C/C++项目自动化构建——Xmake入门指南
- 2025-04-26 AnyCAD Rapid .Net三维控件-WinForms集成教程
- 2025-04-26 编程学习C++语言初级入门100视频课程教程+80套练习题册
- 2025-04-26 环境配置:VSCode 配置 C/C++ 开发环境详细教程( MSVC )
- 2025-04-26 python和c++简单教程初级教学
- 2025-04-26 C++异步从理论到实践总览篇
- 最近发表
- 标签列表
-
- 菜鸟教程 (58)
- jsp (69)
- c++教程 (58)
- gitpush (61)
- pythonif (68)
- pythonifelse (59)
- deletesql (62)
- c++模板 (62)
- c#event (59)
- linuxgzip (68)
- 字符串连接 (73)
- nginx配置文件详解 (61)
- html标签 (69)
- c++初始化列表 (64)
- exec命令 (59)
- canvasfilltext (58)
- mysqlinnodbmyisam区别 (63)
- arraylistadd (66)
- node教程 (59)
- console.table (62)
- c++time_t (58)
- phpcookie (58)
- mysqldatesub函数 (63)
- window10java环境变量设置 (66)
- c++虚函数和纯虚函数的区别 (66)