前言

本教程旨在提取最精炼、实用的C++面试知识点,供读者快速学习及本人查阅复习所用。本文配套精简版本《C++面试宝典》已整理,免费领取地址:https://pan.quark.cn/s/c991f40d40a7

一、delete与delete[]

1.作用

delete和delete[]都是用于释放动态分配的内存的操作符

2.区别

操作符 作用  调用析构函数次数 适用场景
delete 释放单个对象/数组的首元素内存 只调用一次析构函数(对首元素) 配合new分配的单个对象
delete[] 释放整个数组的内存 对数组中每个元素调用析构函数 配合new[]分配ide数组

delete:

        假设指针指向一个通过new分配的对象

        仅调用一次析构函数(如果对象有析构函数)

        释放指针指向的内存块

delete[]:

        假设指针指向一个通过new[]分配的数组首地址

        对数组中的每个元素依次调用析构函数(从最后一个元素到第一个)

        释放整个数组的内存块

3.错误使用后果

用delete释放new[]分配的数组:

        仅调用第一个元素的析构函数,其他元素的析构函数被跳过(可能导致资源泄漏,如未释放的文件句柄、内存等)        

        内存泄漏或未定义行为

用delete[]释放new分配的单对象:

        未定义行为(可能崩溃或内存损坏)

4.示例

4.1 delete示例

#include <iostream>
using namespace std;

class MyClass {
public:
    MyClass() { cout << "Constructor\n"; }
    ~MyClass() { cout << "Destructor\n"; }
};

int main() {
    // 单对象分配
    MyClass* obj = new MyClass; // 调用构造函数
    delete obj;                 // 调用析构函数
    return 0;
}

4.2 delete[]示例

#include <iostream>
using namespace std;

class MyClass {
public:
	MyClass() { cout << "Constructor\n"; }
	~MyClass() { cout << "Destructor\n"; }
};

int main() 
{
	// 数组分配
	MyClass* arr = new MyClass[3]; // 调用3次构造函数
	delete[] arr;                  // 调用3次析构函数(逆序)
	return 0;
}

二、C语言与C++有什么区别?

1.主要区别

特性

C语言 C++
设计目标 过程式编程,贴近硬件 面向对象编程(OOP),兼容过程式
内存管理 malloc/free 手动管理/自动(RALL、智能指针)
函数重载 不支持 支持
标准库 stdio.hstdlib.h STL、iostream等
运行效率 更高(无OOP开销) 略低

2.示例说明

2.1编程规范

C语言:

// C语言:计算两个数的和
#include <stdio.h>
int add(int a, int b) {
    return a + b;
}
int main() {
    int x = 5, y = 3;
    printf("Sum: %d\n", add(x, y));
    return 0;
}

C++:支持面向对象编程(类、继承、多态)

// C++:用类封装加法逻辑
#include <iostream>
class Calculator {
public:
    int add(int a, int b) { return a + b; }
};
int main() {
    Calculator calc;
    int x = 5, y = 3;
    std::cout << "Sum: " << calc.add(x, y) << std::endl;
    return 0;
}

2.2内存管理

C语言:必须手动管理 malloc/free

// C语言:动态分配数组
#include <stdio.h>
#include <stdlib.h>
int main() {
    int* arr = (int*)malloc(5 * sizeof(int));
    if (arr == NULL) {
        printf("Memory allocation failed\n");
        return 1;
    }
    arr[0] = 10;
    free(arr); // 必须手动释放
    return 0;
}

C++:手动管理/智能指针

// C++:使用智能指针管理内存
#include <iostream>
#include <memory>
int main() {
    auto arr = std::make_unique<int[]>(5); // 自动释放
    arr[0] = 10;
    std::cout << arr[0] << std::endl;
    return 0; // 无需手动释放
}

2.3函数重载

C语言:不支持函数重载,函数名必须不同

// C语言:通过不同函数名实现类似重载
#include <stdio.h>
void print_int(int x) { printf("Int: %d\n", x); }
void print_float(float x) { printf("Float: %f\n", x); }
int main() {
    print_int(42);
    print_float(3.14f);
    return 0;
}

C++:支持函数重载,函数名相同,参数不同即可

// C++:函数重载
#include <iostream>
void print(int x) { std::cout << "Int: " << x << std::endl; }
void print(float x) { std::cout << "Float: " << x << std::endl; }
int main() {
    print(42);
    print(3.14f);
    return 0;
}

2.4异常处理

C语言:无内置异常处理,需要通过返回值/errno检查错误

// C语言:通过返回值检查错误
#include <stdio.h>
#include <stdlib.h>
int divide(int a, int b, int* result) {
    if (b == 0) return -1; // 错误码
    *result = a / b;
    return 0;
}
int main() {
    int res;
    if (divide(10, 0, &res) != 0) {
        printf("Error: Division by zero\n");
    }
    return 0;
}

C++:支持try/catch异常处理

// C++:异常处理
#include <iostream>
#include <stdexcept>
int divide(int a, int b) {
    if (b == 0) throw std::runtime_error("Division by zero");
    return a / b;
}
int main() {
    try {
        std::cout << divide(10, 0) << std::endl;
    } catch (const std::exception& e) {
        std::cerr << "Error: " << e.what() << std::endl;
    }
    return 0;
}

2.5泛型编程

C语言:无泛型编程

// C语言:用宏模拟泛型(不安全)
#include <stdio.h>
#define MAX(a, b) ((a) > (b) ? (a) : (b))
int main() {
    printf("Max: %d\n", MAX(5, 3));
    return 0;
}

C++:支持模板 泛型编程

// C++:模板函数
#include <iostream>
template <typename T>
T max(T a, T b) {
    return a > b ? a : b;
}
int main() {
    std::cout << "Max: " << max(5, 3) << std::endl;
    std::cout << "Max: " << max(3.14, 2.71) << std::endl;
    return 0;
}

Logo

Agent 垂直技术社区,欢迎活跃、内容共建。

更多推荐