C++ 知识体系

📚 一、C++ 基础语法

1.1 程序结构

cpp 复制代码
#include <iostream> // 包含标准输入输出库

using namespace std; // 使用标准命名空间(可选,但常见)

int main() {
    cout << "Hello, World!" << endl; // 输出字符串
    return 0; // 返回程序状态(0表示成功)
}
  • #include:预处理器指令,包含头文件。
  • main():程序入口函数,必须存在。
  • cout:输出流对象,<< 是流插入运算符。
  • endl:换行并刷新缓冲区。

注意事项

  • using namespace std; 在大型项目中可能导致命名冲突,建议在函数内使用或显式写 std::cout
  • return 0;main 函数中可省略(C++ 标准规定默认返回 0)。

🧩 二、数据类型与变量

2.1 基本数据类型

类型 大小(字节) 范围
bool 1 true / false
char 1 -128 到 127 或 0 到 255
int 4 -2^31 到 2^31-1
float 4 单精度浮点数
double 8 双精度浮点数
void 无值
cpp 复制代码
#include <iostream>
#include <climits>     // 提供整型极限值
#include <cfloat>       // 提供浮点型极限值

int main() {
    int a = 10;
    double b = 3.14159;
    char c = 'A';
    bool flag = true;

    cout << "int size: " << sizeof(int) << " bytes" << endl;
    cout << "Max int: " << INT_MAX << endl;
    cout << "Min double: " << DBL_MIN << endl;

    return 0;
}

⚠️ 注意事项

  • char 可能是 signedunsigned,取决于编译器,建议明确使用 signed charunsigned char
  • 浮点数比较应避免直接使用 ==,建议使用误差范围。

🔢 三、运算符

3.1 常用运算符

cpp 复制代码
int a = 10, b = 3;

// 算术
int add = a + b;        // 13
int mod = a % b;        // 1

// 关系
bool eq = (a == b);     // false

// 逻辑
bool and_op = (a > 5 && b < 5); // true

// 位运算
int and_bit = a & b;    // 2 (0b1010 & 0b0011)
int left_shift = a << 1; // 20 (左移1位)

// 自增/自减
int x = 5;
int y = ++x; // x=6, y=6 (前缀)
int z = x++; // z=6, x=7 (后缀)

高级用法:位运算常用于状态标志、性能优化。


🧱 四、控制结构

4.1 条件语句

cpp 复制代码
int score = 85;

if (score >= 90) {
    cout << "A";
} else if (score >= 80) {
    cout << "B";  // 输出
} else {
    cout << "C";
}

4.2 循环

cpp 复制代码
// for 循环
for (int i = 0; i < 5; ++i) {
    cout << i << " ";
}

// while
int i = 0;
while (i < 5) {
    cout << i++ << " ";
}

// do-while(至少执行一次)
do {
    cout << i-- << " ";
} while (i > 0);

⚠️ 注意事项

  • 优先使用 ++i 而非 i++ 在循环中(性能更优,尤其对复杂对象)。
  • 避免无限循环,确保循环条件可终止。

📦 五、函数

5.1 函数定义与调用

cpp 复制代码
#include <iostream>
using namespace std;

// 函数声明(可选)
int add(int a, int b);

// 函数定义
int add(int a, int b) {
    return a + b;
}

int main() {
    int result = add(3, 4); // 调用
    cout << result << endl; // 7
    return 0;
}

5.2 函数重载

cpp 复制代码
int add(int a, int b) { return a + b; }
double add(double a, double b) { return a + b; }
string add(string a, string b) { return a + b; }

规则:参数类型、数量或顺序不同即可重载。

5.3 内联函数(inline)

cpp 复制代码
inline int max(int a, int b) {
    return (a > b) ? a : b;
}

用途:减少函数调用开销,适合短小函数。


🔗 六、指针与引用

6.1 指针

cpp 复制代码
int value = 10;
int* ptr = &value;      // 指针指向 value 的地址

cout << *ptr << endl;   // 解引用:输出 10
*ptr = 20;              // 修改 value 的值
cout << value << endl;  // 20

6.2 引用

cpp 复制代码
int a = 10;
int& ref = a;           // ref 是 a 的别名

ref = 20;
cout << a << endl;      // 20

区别

  • 指针可变,引用一旦绑定不能改。
  • 引用必须初始化,指针可以为 nullptr
  • 引用更安全,推荐用于函数参数传递。

6.3 动态内存

cpp 复制代码
int* p = new int(42);   // 动态分配
cout << *p << endl;

delete p;               // 释放内存

// 数组
int* arr = new int[10];
delete[] arr;           // 注意:用 delete[] 释放数组

⚠️ 注意事项

  • 必须配对 new/deletenew[]/delete[]
  • 避免内存泄漏,建议使用智能指针。

🧱 七、数组与字符串

7.1 数组

cpp 复制代码
int arr[5] = {1, 2, 3, 4, 5};

for (int i = 0; i < 5; ++i) {
    cout << arr[i] << " ";
}

// C++11 范围 for
for (int& elem : arr) {
    cout << elem << " ";
}

7.2 字符串

cpp 复制代码
#include <string>

string str = "Hello";
str += " World";
cout << str << endl; // Hello World

cout << str.length() << endl; // 11

建议 :优先使用 std::string 而非 C 风格字符串(char*)。


🏗️ 八、类与对象(面向对象)

8.1 类定义

cpp 复制代码
class Person {
private:
    string name;
    int age;

public:
    // 构造函数
    Person(const string& n, int a) : name(n), age(a) {}

    // 成员函数
    void introduce() const {
        cout << "I'm " << name << ", " << age << " years old." << endl;
    }

    // Getter/Setter
    int getAge() const { return age; }
    void setAge(int a) { if (a > 0) age = a; }
};

8.2 使用

cpp 复制代码
int main() {
    Person p("Alice", 25);
    p.introduce(); // I'm Alice, 25 years old.
    return 0;
}

8.3 构造函数与析构函数

cpp 复制代码
class MyClass {
public:
    MyClass() { cout << "Constructor called" << endl; }
    ~MyClass() { cout << "Destructor called" << endl; }
};

注意:析构函数用于释放资源(如动态内存)。


8.4 拷贝构造函数与赋值运算符

cpp 复制代码
class MyClass {
    int* data;
public:
    // 构造
    MyClass(int val) {
        data = new int(val);
    }

    // 拷贝构造(深拷贝)
    MyClass(const MyClass& other) {
        data = new int(*other.data);
    }

    // 赋值运算符
    MyClass& operator=(const MyClass& other) {
        if (this != &other) {
            delete data;
            data = new int(*other.data);
        }
        return *this;
    }

    // 析构
    ~MyClass() {
        delete data;
    }
};

⚠️ Rule of Three:如果需要自定义析构函数,通常也需要拷贝构造和赋值运算符。


🧬 九、继承与多态

9.1 继承

cpp 复制代码
class Animal {
public:
    virtual void speak() const {
        cout << "Animal sound" << endl;
    }
};

class Dog : public Animal {
public:
    void speak() const override {
        cout << "Woof!" << endl;
    }
};

9.2 多态

cpp 复制代码
Animal* a = new Dog();
a->speak(); // 输出 "Woof!"(动态绑定)

delete a;

关键点

  • 使用 virtual 实现运行时多态。
  • 基类析构函数应为 virtual,否则派生类资源可能无法正确释放。

🧩 十、模板(泛型编程)

10.1 函数模板

cpp 复制代码
template <typename T>
T max(T a, T b) {
    return (a > b) ? a : b;
}

// 使用
int m1 = max(3, 5);        // T = int
double m2 = max(3.1, 2.9); // T = double

10.2 类模板

cpp 复制代码
template <typename T>
class Box {
    T content;
public:
    Box(T c) : content(c) {}
    T get() const { return content; }
};

// 使用
Box<int> intBox(42);
Box<string> strBox("Hello");

优势:代码复用,类型安全。


🧠 十一、STL(标准模板库)

11.1 容器

cpp 复制代码
#include <vector>
#include <map>
#include <set>
#include <algorithm>

vector<int> vec = {1, 2, 3};
vec.push_back(4);

map<string, int> ages;
ages["Alice"] = 25;
ages["Bob"] = 30;

set<int> nums = {1, 2, 2, 3}; // 自动去重

11.2 算法

cpp 复制代码
sort(vec.begin(), vec.end());
auto it = find(vec.begin(), vec.end(), 3);
if (it != vec.end()) {
    cout << "Found at index " << it - vec.begin() << endl;
}

建议:优先使用 STL 容器和算法,高效且安全。


🧰 十二、智能指针(C++11 起)

替代原始指针,自动管理内存。

cpp 复制代码
#include <memory>

// 唯一所有权
unique_ptr<int> uptr = make_unique<int>(42);
// 自动释放,无需 delete

// 共享所有权
shared_ptr<int> sptr1 = make_shared<int>(100);
shared_ptr<int> sptr2 = sptr1; // 引用计数+1
// 当最后一个 shared_ptr 销毁时,自动释放

// 弱引用(避免循环引用)
weak_ptr<int> wptr = sptr1;

最佳实践 :优先使用 make_uniquemake_shared


🧪 十三、异常处理

cpp 复制代码
#include <stdexcept>

void divide(int a, int b) {
    if (b == 0) {
        throw invalid_argument("Division by zero!");
    }
    cout << a / b << endl;
}

int main() {
    try {
        divide(10, 0);
    } catch (const invalid_argument& e) {
        cout << "Error: " << e.what() << endl;
    }
    return 0;
}

⚠️ 建议

  • 不要滥用异常。
  • 抛出对象,捕获引用(避免拷贝)。

🧱 十四、高级特性(C++11/14/17/20)

14.1 auto 与 decltype

cpp 复制代码
auto x = 42;        // x 是 int
auto it = vec.begin(); // 自动推导迭代器类型

decltype(x) y = 10; // y 也是 int

14.2 Lambda 表达式

cpp 复制代码
auto func = [](int a, int b) -> int {
    return a + b;
};

cout << func(3, 4) << endl; // 7

// 捕获外部变量
int multiplier = 2;
auto lambda = [multiplier](int n) {
    return n * multiplier;
};

14.3 移动语义(Move Semantics)

cpp 复制代码
class MyString {
    char* data;
public:
    // 移动构造函数
    MyString(MyString&& other) noexcept {
        data = other.data;
        other.data = nullptr;
    }

    // 移动赋值
    MyString& operator=(MyString&& other) noexcept {
        if (this != &other) {
            delete[] data;
            data = other.data;
            other.data = nullptr;
        }
        return *this;
    }
};

用途:提高性能,避免不必要的拷贝。


🛠️ 十五、注意事项与最佳实践

项目 建议
命名 使用驼峰或下划线,保持一致
内存管理 优先使用智能指针、容器,避免 new/delete
const 正确性 多用 const 修饰变量、函数、参数
头文件保护 使用 #pragma once#ifndef
编译警告 开启 -Wall -Wextra,修复所有警告
RAII 资源获取即初始化,确保异常安全
C++ 标准 尽量使用 C++11 及以上特性
相关推荐
疯狂的沙粒3 小时前
前端开发【工具函数】基于dayjs 封装的DateUtils工具函数,可以直接拿着使用
前端·javascript·vue.js·1024程序员节
郑清3 小时前
Spring AI Alibaba 10分钟快速入门
java·人工智能·后端·ai·1024程序员节·springaialibaba
枫叶丹43 小时前
破局政务数字化核心难题:金仓数据库以国产化方案引领电子证照系统升级之路
数据库·政务·1024程序员节·金仓
你的电影很有趣3 小时前
lesson76:Vue.js 核心特性详解:事件处理、计算属性与侦听器
javascript·vue·1024程序员节
belldeep3 小时前
python:怎样用 Django 开发电子商务程序
django·电子商务·1024程序员节
Neil今天也要学习3 小时前
永磁同步电机无速度算法--基于相位超前校正的LESO
算法·1024程序员节
qq_310658513 小时前
webrtc代码走读(四)-QOS-NACK实现-发送端
c++·webrtc
消失的旧时光-19433 小时前
Kotlin × Gson:为什么遍历 JsonObject 要用 entrySet()
android·kotlin·数据处理·1024程序员节
360智汇云3 小时前
从0到1理解智能体模式
1024程序员节