C++ 基础知识体系与重点梳理

C++ 基础知识体系与重点梳理

一、C++ 基础与入门

1.1 历史、版本与应用领域

C++ 是一种静态类型、编译式、通用的编程语言,支持过程化编程、面向对象编程和泛型编程。其主流版本包括 C++11、C++14、C++17 等,每个版本都引入了新的特性和改进。C++ 广泛应用于服务器端开发、游戏引擎、高性能计算、机器学习框架、嵌入式系统等领域。

1.2 第一个程序与编译运行

#include <iostream> // 包含输入输出流头文件 using namespace std; // 使用标准命名空间int main() { // 主函数,程序入口 cout << "Hello, World!" << endl; // 输出字符串并换行 return 0; // 程序正常结束 }

1.3 命名空间 (Namespace)

命名空间用于解决大型项目中标识符(变量、函数、类名)的命名冲突问题。

  • 定义命名空间
    int value = 10; void myFunction() { /* ... */ } }
  • 使用命名空间
    using namespace MySpace; // 引入整个命名空间 cout << value << endl; // 直接访问 using MySpace::value; // 引入特定成员 cout << value << endl; cout << MySpace::value << endl; // 使用作用域解析符 ::

需记忆重点namespace关键字的作用、using指令的三种用法、::作用域解析符。

二、数据类型、变量与运算符

2.1 基本数据类型

数据类型关键字典型大小(字节)说明
布尔型bool1取值truefalse
字符型char1存储单个字符
整型int4存储整数
浮点型float4单精度浮点数
双精度浮点型double8双精度浮点数
无类型void-表示“无类型”

此外还有short,long,long long,unsigned等修饰符。

2.2 变量与常量

  • 变量定义与初始化
    int a; // 声明 int b = 5; //声明并初始化 (C++98) int c(10); // 直接初始化 int d{15}; // 列表初始化 (C++11),推荐,能防止窄化转换
  • 常量
    const int MAX_SIZE = 100; // 编译时常量,值不可修改 #define PI 3.14159 // 宏定义,预处理阶段替换,无类型检查 ```

需记忆重点:基本数据类型及其大小范围、变量的多种初始化方式、const#define的区别。

2.3 运算符| 类别 | 运算符 | 示例 |

| :--- | :--- | :--- |
| 算术运算符 |+,-,*,/,%|a + b,a % b(取模) |
| 关系运算符 |==,!=,>,<,>=,<=|a == b|
| 逻辑运算符 |&&,||,!|a && b(与) |
| 赋值运算符 |=,+=,-=,*=,/=|a += b(等价于a = a + b) |
| 自增自减 |++,--|i++(后置),++i(前置) |
| 位运算符 |&,|,^,~,<<,>>|a & b(按位与) |

需记忆重点:运算符的优先级和结合性、前置与后置自增/自减的区别、逻辑短路求值。

三、流程控制

// 1. 条件语句 if (condition1) { // ... } else if (condition2) { // ... } else { // ... } // switch 语句 (表达式必须是整型或枚举) switch (expression) { case constant1: // ... break; // 必须用break跳出,否则会穿透 case constant2: // ... break; default: // ... } // 2. 循环语句 // while 循环 while (condition) { // ... } // do-while 循环 (至少执行一次) do { // ... } while (condition); // for 循环for (int i = 0; i < 10; ++i) { // ... } // 3. 跳转语句 break; // 跳出当前循环或switch continue; // 跳过本次循环剩余部分,进入下一次循环 return; // 从函数返回 goto label; // (不推荐使用) 跳转到标签处

需记忆重点if-elseswitch的使用场景、三种循环的区别、breakcontinue的作用。

四、函数

4.1 函数定义与声明

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

4.2 函数参数传递

  • 传值:形参是实参的副本,修改形参不影响实参。
  • 传引用:形参是实参的别名,修改形参即修改实参。需重点掌握
    void swap(int &x, int &y) { // 引用参数 int temp = x; x = y; y = temp; }
  • 传指针:传递地址,通过解引用修改所指内存的值。
  • 常量引用const T&,避免拷贝大型对象,同时防止函数内修改。

4.3 函数重载与默认参数

  • 函数重载:同一作用域内,函数名相同,参数列表(类型、个数、顺序)不同。
    void print(double d); void print(const std::string& s);
  • 默认参数:在函数声明中为参数指定默认值。注意:默认参数必须从右向左连续设置。
    void func(int a, int b = 5, int c = 10); // 正确 // void func(int a = 1, int b, int c); // 错误

需记忆重点:引用传递的原理与优势、函数重载的规则、默认参数的设置规则。

五、数组、指针与引用

5.1 数组

int arr1[5]; // 声明一个包含5个整数的数组 int arr2[3] = {1, 2, 3}; // 声明并初始化 int arr3[] = {1, 2, 3, 4}; // 编译器自动推断大小为4 // 访问元素 arr1[0] = 10; // 下标从0开始 // 数组名在多数情况下会退化为指向其首元素的指针

5.2 指针

指针是存储内存地址的变量。

int var = 20; int *ptr = &var; // ptr 指向 var 的地址 cout << *ptr << endl; // 解引用,输出 20 *ptr = 30; // 通过指针修改变量的值 // 动态内存分配 (需与 delete 配对使用) int *p = new int; // 在堆上分配一个int *p = 5; delete p; // 释放内存 p = nullptr; // 将指针置空,避免野指针 int *arr = new int[10]; // 动态分配数组 delete[] arr; // 释放数组内存

5.3 引用

引用是变量的别名,必须在定义时初始化,且一旦绑定不能更改指向。

int a = 10; int &ref = a; // ref 是 a 的引用 ref = 20; // 相当于 a = 20

需记忆重点:数组与指针的关系(数组名退化)、new/deletenew[]/delete[]必须配对使用、引用的本质与限制、野指针和空指针的概念。

六、类与对象 (面向对象核心)

6.1 类的定义与对象创建

class Student { // 类定义 private: // 私有成员,类外不可直接访问 string name; int age; public: // 公有成员,类外可以访问 // 成员函数声明 void setName(string n); void setAge(int a); void display(); }; // 注意分号 // 成员函数定义 void Student::setName(string n) { name = n; } // 创建对象 Student stu1; // 栈上对象 Student *stu2 = new Student(); // 堆上对象,需手动delete

6.2 构造函数与析构函数

  • 构造函数:对象创建时自动调用,用于初始化。
    public: MyClass() { /* 默认构造函数 */ } MyClass(int x) { /* 带参构造函数 */ } MyClass(const MyClass &obj) { /* 拷贝构造函数 */ } };
  • 析构函数:对象销毁时自动调用,用于清理资源(如释放动态内存)。
    ~MyClass() { // 清理工作 }

6.3 访问控制与封装

访问限定符类内访问类外访问友元/派生类访问
public
protected✔ (派生类可访问)
private✔ (仅友元)

封装是将数据(属性)和操作数据的方法(函数)捆绑在一起,并对外隐藏实现细节。

6.4 特殊成员*this指针:指向当前对象的指针,在非静态成员函数内部可用。

  • 静态成员:属于类本身,而非某个对象。所有对象共享同一份静态成员。
    public: static int count; // 静态成员变量声明 static void func() { /* 静态成员函数 */ } }; int MyClass::count = 0; // 静态成员变量必须在类外定义和初始化
  • 友元friend关键字允许一个函数或类访问另一个类的私有成员。破坏了封装,应谨慎使用。

6.5 深拷贝与浅拷贝

  • 浅拷贝:默认的拷贝构造函数和赋值运算符进行按成员复制。如果类中有指针成员,会导致两个对象的指针指向同一块内存。
  • 深拷贝:需要自定义拷贝构造函数和赋值运算符,为指针成员重新分配内存并复制内容。
    char* data; public: // 深拷贝构造函数 String(const String& other) { data = new char[strlen(other.data) + 1]; strcpy(data, other.data); } // 深拷贝赋值运算符 String& operator=(const String& other) { if (this != &other) { delete[] data; data = new char[strlen(other.data) + 1]; strcpy(data, other.data); } return *this; } ~String() { delete[] data; } };

需记忆重点:类的基本语法、三种访问权限的区别、构造函数/析构函数的调用时机、this指针的用途、静态成员的特点、深拷贝与浅拷贝的区别及实现。

七、继承与多态

7.1 继承

继承允许我们依据另一个类来定义一个类,实现代码复用。

class BaseClass { // 基类成员}; class DerivedClass : public BaseClass { // 公有继承 // 派生类新增成员 };

继承方式:publicprotectedprivate,影响基类成员在派生类中的访问权限。

7.2 多态与虚函数

多态允许使用基类的指针或引用来调用派生类的函数。

class Animal { public: virtual void makeSound() { // 虚函数 cout << "Animal sound" << endl; } virtual ~Animal() {} // 虚析构函数,确保正确释放派生类资源 }; class Dog : public Animal { public: void makeSound() override { //重写虚函数 cout << "Woof!" << endl; } }; int main() { Animal* myAnimal = new Dog(); myAnimal->makeSound(); // 输出 "Woof!",多态发生 delete myAnimal; return 0; }
  • 虚函数:使用virtual关键字声明。允许在派生类中被重写。
  • 纯虚函数与抽象类:包含纯虚函数(virtual void func() = 0;)的类是抽象类,不能实例化。
  • override关键字(C++11):显式注明重写基类虚函数,提高代码可读性并让编译器检查。
  • 虚析构函数:基类析构函数应为虚函数,以确保通过基类指针删除派生类对象时能正确调用派生类的析构函数。

需记忆重点:三种继承方式的区别、多态的实现原理(虚函数表)、虚函数和纯虚函数的定义、overridefinal关键字的作用、为何需要虚析构函数。

八、运算符重载

允许为用户定义的类型(类)重新定义运算符的含义。

class Complex { private: double real, imag; public: Complex operator+(const Complex& other) const { return Complex(real + other.real, imag + other.imag); } // 重载输出流运算符 << (通常声明为友元) friend ostream& operator<<(ostream& os, const Complex& c); }; ostream& operator<<(ostream& os, const Complex& c) { os << c.real << " + " << c.imag << "i"; return os; }

需记忆重点:可重载的运算符列表、成员函数重载与全局函数重载的区别、输入输出流运算符>><<的重载方式。

九、模板与 STL

9.1 函数模板与类模板

模板是泛型编程的基础,允许编写与类型无关的代码。

// 函数模板 template <typename T> T max(T a, T b) { return (a > b) ? a : b; } // 类模板 template <class T> class Box { T content; public: void setContent(T newContent) { content = newContent; } T getContent() { return content; } }; // 使用 int i = max<int>(10, 5); Box<string> stringBox;

9.2标准模板库 (STL) 核心组件

STL 提供了丰富的通用数据结构和算法。

组件类别代表说明
容器vector,list,deque,map,set,unordered_map用于存储数据的通用数据结构。
迭代器begin(),end()提供一种方法来顺序访问容器中的元素。
算法sort(),find(),copy()作用于容器上的函数模板,如排序、查找。
函数对象greater<int>(),less<int>()行为类似函数的对象,常用于算法中定义操作。
#include <vector> #include <algorithm> #include <iostream> int main() { std::vector<int> vec = {5, 2, 8, 1, 9}; std::sort(vec.begin(), vec.end()); // 排序 for (int num : vec) { // 范围for循环 (C++11) std::cout << num << " "; } return 0; }

需记忆重点:模板的基本语法、typenameclass在模板中的等价性、STL 的六大组件、常用容器(vector,map)和算法(sort,find)的基本用法。

十、输入输出流与文件操作

10.1 标准 I/O 流

#include <iostream> using namespace std; int num; cin >> num; // 从标准输入读取 cout << "Number is: " << num << endl; // 输出到标准输出 cerr << "Error message" << endl; // 输出到标准错误 (无缓冲) clog << "Log message" << endl; // 输出到标准日志 (有缓冲)

10.2 文件 I/O

#include <fstream> using namespace std; // 写文件 ofstream outFile("test.txt"); if (outFile.is_open()) { outFile << "Hello File!" << endl; outFile.close(); } // 读文件 ifstream inFile("test.txt"); string line; if (inFile.is_open()) { while (getline(inFile, line)) { cout << line << endl; } inFile.close(); }

需记忆重点cin/cout的使用、文件流对象 (ifstream,ofstream,fstream) 的打开、读写和关闭操作。

十一、异常处理

#include <iostream> #include <stdexcept> using namespace std; double divide(double a, double b) { if (b == 0) { throw runtime_error("Division by zero!"); // 抛出异常 } return a / b; } int main() { try { double result = divide(10, 0); cout << result << endl; } catch (const runtime_error& e) { // 捕获特定异常 cerr << "Error: " << e.what() << endl; } catch (...) { // 捕获所有其他异常 cerr << "Unknown error occurred." << endl; } return 0; }

需记忆重点trycatchthrow的用法、异常类的继承体系(std::exception)、自定义异常类。

十二、C++11/14/17 关键新特性 (需了解)

  • 自动类型推导auto关键字。
  • 范围 for 循环for (auto& elem : container)
  • 智能指针unique_ptr,shared_ptr,weak_ptr,用于自动管理动态内存,避免内存泄漏。
  • Lambda 表达式:匿名函数对象。
  • 右值引用与移动语义T&&std::move,提升性能。
  • nullptr:空指针常量,替代NULL

需记忆重点auto的使用场景、范围 for 循环语法、三种智能指针的所有权语义、Lambda 表达式的基本格式。


参考来源

  • Cpp入门基础
  • NX二次开发超详细知识点教程 NX二次开发重点内容总结
  • C++ 类与对象零基础详细知识点总结
  • C++程序设计重点总结(谭浩强版)
  • C++大学教程:关键章节答案解析(12-24)