从 C 转向 C++ 的过程

首先是 C 到 C++ 的过渡的基础特性

1. C++ 中改进的 C 代码中潜在危险操作

C 中的问题 C++ 解法 为什么更好
手动 malloc/free → 内存泄漏 RAII + 智能指针 std::unique_ptr<T>, std::shared_ptr<T> 自动释放,异常安全
数组越界、忘记 \0 std::vector<T>, std::string 自动管理大小,支持 size(), push_back()
函数参数传递大结构体(值拷贝开销) const T& 引用传参 零拷贝,语义清晰
宏定义(#define MAX 100 constexpr int MAX = 100; 类型安全,作用域可控

2. 结构体---类的过渡

场景 C++ 方案 对比 C
封装数据+操作(如 socket、file handle) class / struct + 成员函数 比 C 的 struct + function pointers 更简洁
多态(不同设备执行不同操作) 虚函数(virtual) 比 C 的 switch(type) 或函数指针表更安全
泛型(通用容器/算法) 模板(template) 比 C 的 void* 宏更类型安全

2.0 结构体与封装

c 复制代码
#include <stdio.h>

// 仅仅是数据的集合
typedef struct {
    char name[50];
    int age;
} Person;

// 操作数据的函数是独立的
void Person_init(Person* p, const char* name, int age) {
    strcpy(p->name, name);
    p->age = age;
}

void Person_print(Person* p) {
    printf("Name: %s, Age: %d\n", p->name, p->age);
}

// 使用
void c_struct_test() {
    Person p; // 数据未初始化,里面是垃圾值
    Person_init(&p, "Tom", 25); // 必须记得调用初始化
    Person_print(&p);
}
cpp 复制代码
#include <iostream>
#include <string>

class Person {
private: // 私有成员,外部无法直接乱改
    std::string name;
    int age;

public:
    // 构造函数:创建对象时自动调用,保证初始化
    Person(std::string n, int a) : name(n), age(a) {}

    // 成员函数:直接操作内部数据
    void print() const {
        std::cout << "Name: " << name << ", Age: " << age << std::endl;
    }
};

// 使用
void cpp_class_test() {
    // Person p; // 编译错误!因为没有提供 name 和 age,禁止创建未初始化的对象
    
    Person p("Tom", 25); // 创建即初始化
    p.print(); 
}

2.1 【malloc/free】 vs 【RAll】

  • C 的思维:申请内存 --- 使用 --- 释放内存
  • C++ 的思维:使用 std::vector 或者 std::unique_ptr ,对象创建时自动申请资源,对象超多作用范围时,析构函数自动释放资源。

2.2 字符串管理

  • C的思维:字符串就是以 \0 结尾的字符数组,计算长度要 strlen,拼接要 strcat,不仅麻烦还容易越界。
  • C++的思维:使用 std::stringstd::vector。它们会自动管理内存大小,自动扩容,且自带长度记录。
c 复制代码
// C 字符串拼接
const char* s1 = "Hello";
const char* s2 = " World";
int len = strlen(s1) + strlen(s2) + 1;
char* result = (char*)malloc(len * sizeof(char));
strcpy(result, s1);
strcat(result, s2);
free(result);
cpp 复制代码
// C++ 字符串拼接
std::string s1 = "Hello";
std::string s2 = " World";
std::string result = s1 + s2;

2.3 动态数组

c 复制代码
 // C
 int size = 5;
 int* arr = (int*)malloc(size * sizeof(int));

// c++
std::vector<int> arr = {0, 10, 20, 30, 40}; 
arr.push_back(50);

2.4 智能指针

c 复制代码
int process_data_c() {
    int* ptr = (int*)malloc(sizeof(int));
    *ptr = 100;

    if (*ptr > 50) {
        // 糟糕!如果你这里直接 return,ptr指向的内存就泄露了
        // 你必须记得写 free(ptr);
        return -1; 
    }

    free(ptr);
    return 0;
}
cpp 复制代码
#include <memory> // 引入智能指针

int process_data_cpp() {
    // unique_ptr 独占这个指针的所有权
    // make_unique 是 C++14 引入的,比 new 更安全
    std::unique_ptr<int> ptr = std::make_unique<int>(100);

    if (*ptr > 50) {
        // 即使在这里 return
        // ptr 是栈上的对象,它的析构函数会被调用
        // 析构函数会自动 free 掉它管理的堆内存
        return -1; 
    }

    // 函数结束,自动释放
    return 0;
}
相关推荐
daidaidaiyu2 小时前
一文入门 Android NDK 开发
c++
难得的我们2 小时前
C++与区块链智能合约
开发语言·c++·算法
jllllyuz2 小时前
基于MATLAB的D2D通信模式选择仿真
开发语言·网络·matlab
kaikaile19952 小时前
基于ADMM的TV正则化稀疏重建MATLAB实现
开发语言·matlab
diediedei2 小时前
C++编译期正则表达式
开发语言·c++·算法
学海无涯书山有路2 小时前
Android FragmentContainerView 新手详解(Java 版)
android·java·开发语言
XiYang-DING3 小时前
【Java SE】数据类型、变量、类型转换、运算符以及程序逻辑控制
java·开发语言
Tianwen_Burning3 小时前
c++ release下的debug
c++
独自破碎E3 小时前
JDK版本的区别
java·开发语言