C++编程从入门到实践:面向对象与STL核心特性详解
C作为一门功能强大的编程语言在系统开发、游戏引擎、高性能计算等领域有着广泛应用。对于已经掌握C语言基础的程序员来说学习C不仅是语法上的扩展更是编程思维从面向过程到面向对象的重大转变。本文基于北京大学《C程序设计》课程的核心内容结合当前C开发的实际需求重点讲解C语言的基础特性和面向对象编程思想。无论你是准备面试C岗位还是想要开发更复杂的应用程序掌握这些基础知识都至关重要。1. C核心能力速览能力项说明语言类型静态类型、编译型、多范式编程语言主要特性面向对象、泛型编程、内存管理、运算符重载开发环境Visual Studio、CLion、VSCode、GCC/Clang适用场景系统软件、游戏开发、嵌入式系统、高性能计算学习前提建议具备C语言基础和基本算法知识2. 从C到C的平滑过渡2.1 C对C语言的扩展C在C语言基础上增加了许多重要特性这些特性使得编程更加安全和高效// 引用C的重要扩展 #include iostream using namespace std; void swap(int a, int b) { int temp a; a b; b temp; } int main() { int x 5, y 10; swap(x, y); // 直接传递变量无需取地址 cout x x , y y endl; return 0; }引用Reference是C中非常重要的概念它提供了指针的替代方案使代码更加简洁安全。与指针不同引用必须在声明时初始化且不能改变指向的对象。2.2 const关键字和常量定义// const关键字的使用 const int MAX_SIZE 100; // 常量定义 const double PI 3.14159; void printArray(const int arr[], int size) { // arr被声明为const不能在函数内修改 for(int i 0; i size; i) { cout arr[i] ; } cout endl; }const关键字不仅用于定义常量还能保护函数参数不被意外修改提高代码的健壮性。3. 面向对象编程基础3.1 类和对象的概念类是C面向对象编程的核心它将数据和对数据的操作封装在一起// 简单的类定义示例 class Student { private: string name; int age; double score; public: // 构造函数 Student(string n, int a, double s) : name(n), age(a), score(s) {} // 成员函数 void displayInfo() { cout 姓名 name endl; cout 年龄 age endl; cout 成绩 score endl; } // 设置成绩 void setScore(double s) { if(s 0 s 100) { score s; } } // 获取成绩 double getScore() const { return score; } }; // 使用示例 int main() { Student stu(张三, 20, 85.5); stu.displayInfo(); stu.setScore(90.0); cout 新成绩 stu.getScore() endl; return 0; }3.2 构造函数和析构函数构造函数在对象创建时自动调用析构函数在对象销毁时自动调用class String { private: char *str; int length; public: // 默认构造函数 String() : str(nullptr), length(0) { cout 默认构造函数被调用 endl; } // 参数化构造函数 String(const char *s) { length strlen(s); str new char[length 1]; strcpy(str, s); cout 参数化构造函数被调用 endl; } // 拷贝构造函数 String(const String other) { length other.length; str new char[length 1]; strcpy(str, other.str); cout 拷贝构造函数被调用 endl; } // 析构函数 ~String() { delete[] str; cout 析构函数被调用 endl; } void print() const { if(str) cout str endl; } };4. 运算符重载运算符重载让自定义类型能够像内置类型一样使用运算符class Complex { private: double real; double imag; public: Complex(double r 0, double i 0) : real(r), imag(i) {} // 重载运算符 Complex operator(const Complex other) const { return Complex(real other.real, imag other.imag); } // 重载-运算符 Complex operator-(const Complex other) const { return Complex(real - other.real, imag - other.imag); } // 重载输出运算符友元函数 friend ostream operator(ostream os, const Complex c) { os c.real c.imag i; return os; } }; // 使用示例 int main() { Complex c1(3, 4); Complex c2(1, 2); Complex c3 c1 c2; cout c1 c2 c3 endl; return 0; }5. 继承与多态5.1 继承的基本概念继承是面向对象的重要特性允许创建层次化的类结构// 基类 class Shape { protected: string color; public: Shape(string c) : color(c) {} virtual double area() const 0; // 纯虚函数 virtual void draw() const { cout 绘制 color 的图形 endl; } }; // 派生类 class Circle : public Shape { private: double radius; public: Circle(string c, double r) : Shape(c), radius(r) {} double area() const override { return 3.14159 * radius * radius; } void draw() const override { cout 绘制 color 的圆形半径 radius endl; } }; class Rectangle : public Shape { private: double width, height; public: Rectangle(string c, double w, double h) : Shape(c), width(w), height(h) {} double area() const override { return width * height; } void draw() const override { cout 绘制 color 的矩形尺寸 width x height endl; } };5.2 多态的实现多态允许使用基类指针调用派生类的方法void demonstratePolymorphism() { Shape *shapes[3]; shapes[0] new Circle(红色, 5.0); shapes[1] new Rectangle(蓝色, 4.0, 6.0); shapes[2] new Circle(绿色, 3.0); for(int i 0; i 3; i) { shapes[i]-draw(); cout 面积 shapes[i]-area() endl; cout -------- endl; } // 释放内存 for(int i 0; i 3; i) { delete shapes[i]; } }6. 模板编程模板是C泛型编程的基础允许编写与数据类型无关的代码6.1 函数模板// 函数模板示例 templatetypename T T max(T a, T b) { return (a b) ? a : b; } templatetypename T void swap(T a, T b) { T temp a; a b; b temp; } // 使用示例 void templateDemo() { int a 5, b 10; cout 较大值 max(a, b) endl; double x 3.14, y 2.71; swap(x, y); cout 交换后x x , y y endl; }6.2 类模板// 类模板示例简单的栈实现 templatetypename T, int MAX_SIZE 100 class Stack { private: T data[MAX_SIZE]; int topIndex; public: Stack() : topIndex(-1) {} void push(const T item) { if(topIndex MAX_SIZE - 1) { data[topIndex] item; } } T pop() { if(topIndex 0) { return data[topIndex--]; } return T(); // 返回默认值 } bool isEmpty() const { return topIndex -1; } int size() const { return topIndex 1; } }; // 使用示例 void stackDemo() { Stackint intStack; intStack.push(1); intStack.push(2); intStack.push(3); while(!intStack.isEmpty()) { cout intStack.pop() ; } cout endl; }7. 标准模板库STL基础STL是C标准库的重要组成部分提供了丰富的容器和算法7.1 常用容器#include vector #include list #include map #include algorithm void stlContainerDemo() { // vector示例 vectorint vec {1, 2, 3, 4, 5}; vec.push_back(6); cout vector元素; for(auto it vec.begin(); it ! vec.end(); it) { cout *it ; } cout endl; // list示例 liststring names {Alice, Bob, Charlie}; names.push_back(David); cout list元素; for(const auto name : names) { cout name ; } cout endl; // map示例 mapstring, int scores; scores[Alice] 95; scores[Bob] 87; scores[Charlie] 92; cout map元素 endl; for(const auto pair : scores) { cout pair.first : pair.second endl; } }7.2 算法使用void stlAlgorithmDemo() { vectorint numbers {3, 1, 4, 1, 5, 9, 2, 6}; // 排序 sort(numbers.begin(), numbers.end()); cout 排序后; for(int num : numbers) { cout num ; } cout endl; // 查找 auto it find(numbers.begin(), numbers.end(), 5); if(it ! numbers.end()) { cout 找到元素5位置 distance(numbers.begin(), it) endl; } // 反转 reverse(numbers.begin(), numbers.end()); cout 反转后; for(int num : numbers) { cout num ; } cout endl; }8. 文件操作C提供了强大的文件操作功能#include fstream #include sstream void fileOperationDemo() { // 写入文件 ofstream outFile(data.txt); if(outFile.is_open()) { outFile Hello, C File IO! endl; outFile 这是第二行内容 endl; outFile.close(); cout 文件写入成功 endl; } // 读取文件 ifstream inFile(data.txt); string line; if(inFile.is_open()) { cout 文件内容 endl; while(getline(inFile, line)) { cout line endl; } inFile.close(); } // 字符串流 stringstream ss; ss 姓名李四 endl; ss 年龄25 endl; ss 成绩88.5 endl; cout 字符串流内容 endl; cout ss.str(); }9. 异常处理良好的异常处理机制可以提高程序的健壮性class DivisionByZeroException : public exception { public: const char* what() const noexcept override { return 除零错误除数不能为零; } }; double safeDivide(double a, double b) { if(b 0) { throw DivisionByZeroException(); } return a / b; } void exceptionHandlingDemo() { try { double result1 safeDivide(10, 2); cout 10 / 2 result1 endl; double result2 safeDivide(5, 0); // 会抛出异常 cout 5 / 0 result2 endl; } catch(const DivisionByZeroException e) { cout 捕获到异常 e.what() endl; } catch(const exception e) { cout 捕获到其他异常 e.what() endl; } cout 程序继续执行... endl; }10. 现代C特性C11/14/1710.1 自动类型推导void modernCppDemo() { // auto关键字 auto x 42; // int auto y 3.14; // double auto name C; // const char* vectorint numbers {1, 2, 3, 4, 5}; // 范围for循环 cout 范围for循环; for(auto num : numbers) { cout num ; } cout endl; // lambda表达式 auto square [](int n) { return n * n; }; cout 5的平方 square(5) endl; // 使用lambda进行排序 vectorstring words {apple, banana, cherry, date}; sort(words.begin(), words.end(), [](const string a, const string b) { return a.length() b.length(); }); cout 按长度排序; for(const auto word : words) { cout word ; } cout endl; }10.2 智能指针#include memory void smartPointerDemo() { // unique_ptr独占所有权 unique_ptrint ptr1 make_uniqueint(42); cout unique_ptr值 *ptr1 endl; // shared_ptr共享所有权 shared_ptrstring ptr2 make_sharedstring(Hello); shared_ptrstring ptr3 ptr2; // 共享所有权 cout shared_ptr值 *ptr2 endl; cout 引用计数 ptr2.use_count() endl; // weak_ptr不增加引用计数 weak_ptrstring weakPtr ptr2; if(auto sharedPtr weakPtr.lock()) { cout weak_ptr获取的值 *sharedPtr endl; } }11. 实战项目学生管理系统下面是一个综合运用C特性的简单学生管理系统#include iostream #include vector #include memory #include algorithm class Student { private: string name; int id; double score; public: Student(string n, int i, double s) : name(n), id(i), score(s) {} string getName() const { return name; } int getId() const { return id; } double getScore() const { return score; } void setScore(double s) { score s; } void display() const { cout 学号 id 姓名 name 成绩 score endl; } }; class StudentManager { private: vectorshared_ptrStudent students; public: void addStudent(const string name, int id, double score) { auto student make_sharedStudent(name, id, score); students.push_back(student); cout 添加学生成功 endl; } void displayAll() const { if(students.empty()) { cout 暂无学生信息 endl; return; } cout 所有学生信息 endl; for(const auto student : students) { student-display(); } } shared_ptrStudent findStudent(int id) const { auto it find_if(students.begin(), students.end(), [id](const shared_ptrStudent s) { return s-getId() id; }); if(it ! students.end()) { return *it; } return nullptr; } void sortByScore() { sort(students.begin(), students.end(), [](const shared_ptrStudent a, const shared_ptrStudent b) { return a-getScore() b-getScore(); }); cout 按成绩排序完成 endl; } }; // 使用示例 void studentSystemDemo() { StudentManager manager; manager.addStudent(张三, 1001, 85.5); manager.addStudent(李四, 1002, 92.0); manager.addStudent(王五, 1003, 78.5); cout \n--- 显示所有学生 --- endl; manager.displayAll(); cout \n--- 查找学号1002的学生 --- endl; auto student manager.findStudent(1002); if(student) { student-display(); } else { cout 未找到该学生 endl; } cout \n--- 按成绩排序后 --- endl; manager.sortByScore(); manager.displayAll(); }12. 常见问题与解决方案12.1 内存管理问题问题内存泄漏// 错误示例 void memoryLeakDemo() { int *ptr new int[100]; // 分配内存 // 忘记delete[] ptr; // 内存泄漏 } // 正确做法 void correctMemoryDemo() { // 使用智能指针 auto ptr make_uniqueint[](100); // 自动释放内存 }问题野指针// 错误示例 void wildPointerDemo() { int *ptr new int(42); delete ptr; // ptr现在成为野指针 *ptr 100; // 未定义行为 } // 正确做法 void correctPointerDemo() { auto ptr make_uniqueint(42); // 不需要手动delete // ptr离开作用域时自动释放 }12.2 编译错误排查常见编译错误及解决方法未定义引用错误检查函数声明和定义是否匹配链接是否正确模板实例化错误确保模板参数满足要求类型不匹配检查函数参数类型和返回值类型头文件包含问题确保必要的头文件都已包含13. 开发环境配置建议13.1 VSCode配置// .vscode/settings.json { C_Cpp.default.cppStandard: c17, C_Cpp.default.intelliSenseMode: gcc-x64, files.associations: { *.cpp: cpp } }13.2 编译命令示例# 使用g编译 g -stdc17 -Wall -Wextra -O2 main.cpp -o program # 使用CMake cmake_minimum_required(VERSION 3.10) project(MyProject) set(CMAKE_CXX_STANDARD 17) add_executable(program main.cpp)14. 学习路径建议基础阶段掌握C基本语法、面向对象概念进阶阶段学习模板、STL、异常处理高级阶段深入理解现代C特性、内存模型、多线程实战阶段参与实际项目开发阅读优秀开源代码通过系统学习C语言基础你不仅能够编写更复杂的程序还能更好地理解计算机系统的工作原理。建议在学习过程中多动手实践从简单程序开始逐步挑战更复杂的项目。