[C.C++] 初识C++(入门)

959 0
Honkers 2025-8-13 17:15:29 | 显示全部楼层 |阅读模式

C++简单介绍

一、C++简介与核心增强
  1. C++起源

    • 由Bjarne Stroustrup于1982年在C语言基础上扩展面向对象特性而来,完全兼容C语言。

    • 核心目标:提供更高效的抽象机制(如类、模板),支持复杂软件开发。

  2. C++对C语言的增强

    • 命名空间:解决全局符号(变量、函数)命名冲突问题。

    • 引用:提供变量的别名,避免指针的复杂操作。

    • 函数与运算符重载:允许同名函数根据参数类型/数量区分功能。

    • 面向对象:封装、继承、多态(未在示例中展开)。

    • 泛型编程:模板(template)支持类型无关的代码。

    • 异常处理:try/catch机制增强错误处理能力。

    • STL(标准模板库):提供通用容器(如vector、map)和算法。

  3. C++编译器与开发环境

    • gcc与g++的区别

      • gcc默认按C语言编译.c文件,g++统一按C++编译。

      • 链接阶段,g++自动链接C++标准库(如libstdc++),gcc需手动指定。

    • Linux下安装g++

sudo apt-get install g++
g++ -v  # 验证安装 

 编译运行示例

  1. #include <iostream>
  2. using namespace std;
  3. int main() {
  4. cout << "Hello World" << endl;
  5. return 0;
  6. }
复制代码

编译命令:g++ HelloWorld.cpp -o output && ./output

4.常见编译警告与解决

  • 字符串常量转换警告

char* str = "Hello C++";         // 错误:C++禁止字符串常量转为char*

解决方案

  1. const char* str = "Hello C++"; // 只读访问
  2. char str[] = "Hello C++"; // 可修改的字符数组
复制代码
二、命名空间(Namespace)详解
  1. 命名空间的作用

    • 解决全局作用域中符号(变量、函数、类)的命名冲突问题。

    • 允许将代码逻辑分组,增强可维护性。

    • 命名空间的定义与声明

      定义语法
  1. namespace NamespaceName {
  2. int var; // 变量
  3. void func() { ... } // 函数
  4. class MyClass { ... }; // 类
  5. }
复制代码

                示例

  1. namespace A {
  2. int global = 10;
  3. void function() { cout << "Namespace A" << endl; }
  4. }
  5. namespace B {
  6. int global = 20;
  7. void function() { cout << "Namespace B" << endl; }
  8. }
复制代码

3.命名空间成员的使用

  • 作用域解析符(::)

  1. A::global = 100; // 访问A命名空间的global变量
  2. B::function(); // 调用B命名空间的函数
复制代码

using namespace声明

  1. using namespace A;
  2. global = 100; // 直接使用A中的global
  3. function(); // 直接调用A中的function
复制代码

using声明单个成员

  1. using A::global; // 仅引入A中的global
  2. global = 100; // 直接访问
复制代码

 4.命名空间的别名

  • 语法:namespace Alias = OriginalNamespace;

  • 示例

namespace A_Alias = A;
cout << A_Alias::global << endl;         // 等同于A::global

5.特殊命名空间

  • 全局命名空间

    • 隐式存在,所有全局变量和函数属于该空间。

    • 访问方式:::global_var 或 ::function()。

  1. int global = 50;
  2. int main() {
  3. ::global = 100; // 显式访问全局命名空间
  4. return 0;
  5. }
复制代码

匿名命名空间

  • 成员仅在当前文件内可见(类似C的static)

  1. namespace {
  2. int local_var = 10; // 仅在当前文件有效
  3. void local_func() { ... }
  4. }
复制代码

6.跨文件命名空间任务示例

  • 文件a.cpp

  1. #include "space.h"
  2. namespace A_Space {
  3. int calc(int a, int b) { return a + b; }
  4. }
复制代码
  • 文件b.cpp
  1. #include "space.h"
  2. namespace B_Space {
  3. int calc(int a, int b) { return a - b; }
  4. }
复制代码
  • 头文件space.h
  1. #ifndef SPACE_H
  2. #define SPACE_H
  3. namespace A_Space { extern int calc(int a, int b); }
  4. namespace B_Space { extern int calc(int a, int b); }
  5. #endif
复制代码
  • 主文件main.cpp
  1. #include "space.h"
  2. #include <iostream>
  3. using namespace std;
  4. int main() {
  5. cout << A_Space::calc(5, 3) << endl; // 输出8
  6. cout << B_Space::calc(5, 3) << endl; // 输出2
  7. return 0;
  8. }
复制代码

三、关键总结与对比

特性C语言C++增强
命名冲突解决无机制,依赖唯一命名命名空间分组管理
字符串常量处允许char* str = "str"需用const char*或字符数组
函数重载不支持支持,根据参数类型/数量区分
作用域访问全局变量直接访问支持::、using声明等方式

引用

一、引用的基本概念
  1. 定义
    引用(Reference)是C++中为变量或对象创建的别名,与目标变量绑定后,对引用的操作等同于直接操作目标变量。

    • 语法:类型 &引用名 = 目标变量;

    • 示例

      1. int data = 100;
      2. int &quote = data; // quote是data的别名
      3. quote = 200; // 等同于data = 200
      4. cout << data; // 输出200
      复制代码
  2. 核心特性

    • 必须初始化:定义引用时必须绑定到目标变量。

      1. int &ref; // 错误:未初始化
      复制代码
    • 类型一致:引用类型必须与目标变量类型一致。

      1. double a = 10.3;
      2. int &b = a; // 错误:类型不匹配
      复制代码
    • 不可重新绑定:引用一旦初始化后,不能再绑定到其他变量。

      1. int x = 10, y = 20;
      2. int &ref = x;
      3. ref = y; // 正确:将y的值赋给x(x=20)
      4. // &ref = y; // 错误:不能修改引用的绑定目标
      复制代码

二、引用的本质

底层实现
        引用在底层通过指针实现,编译器将其转换为指针操作,但语法上更安全简洁

  1. int data = 10;
  2. int &ref = data; // 编译器转换为 int* const ref = &data;
  3. ref = 20; // 转换为 *ref = 20;
复制代码

三、引用的应用场景
  1. 作为函数参数
    通过引用传参,避免拷贝开销并允许修改实参。

    1. void swap(int &a, int &b) {
    2. int temp = a;
    3. a = b;
    4. b = temp;
    5. }
    6. int main() {
    7. int x = 10, y = 20;
    8. swap(x, y); // x=20, y=10
    9. }
    复制代码
  2. 作为函数返回值
    返回引用可避免拷贝,但需确保返回的引用不指向局部变量(否则悬空引用)。

    1. // 错误示例:返回局部变量的引用
    2. int& func() {
    3. int x = 10;
    4. return x; // x在函数结束后销毁,引用无效
    5. }
    6. // 正确示例:返回全局变量或静态变量的引用
    7. int global = 10;
    8. int& getGlobal() {
    9. return global;
    10. }
    复制代码
  3. 对指针和数组的引用

    • 指针的引用

      1. int data = 10;
      2. int *ptr = &data;
      3. int* &ref_ptr = ptr; // ref_ptr是ptr的别名
      4. *ref_ptr = 20; // data=20
      复制代码
    • 数组的引用

      1.  int arr[3] = {1, 2, 3}; int (&ref_arr)[3] = arr; // ref_arr是数组arr的别名 cout << sizeof(ref_arr); // 输出12(假设int为4字节)
      复制代码

四、常引用(const引用)
  1. 定义
    使用const修饰的引用,禁止通过引用修改目标变量。

    • 语法:const 类型 &引用名 = 目标变量;

    • 示例

      1. int num = 100;
      2. const int &cref = num;
      3. // cref = 200; // 错误:不能通过常引用修改值
      4. num = 200; // 正确:直接修改原变量
      复制代码
  2. 绑定规则

    • 可以绑定到常量或非常量,但不可通过常引用修改目标。

    • 可以绑定到临时对象(如字面量、表达式结果)。

      1. const int &ref = 10; // 正确
      2. const double &dref = 3.14; // 正确
      复制代码
  3. 应用场景

    • 函数参数传递时保护数据不被修改。

    • 避免拷贝大型对象(如传递const string&)。


五、引用与指针的对比
特性引用指针
初始化要求必须初始化可以不初始化(但可能野指针)
空值合法性不允许空值允许nullptr
重新绑定不可重新绑定可以指向不同对象
操作语法直接使用别名(无需解引用)需通过*或->操作
内存占用无额外内存(编译器优化为指针)占用内存存储地址
多级间接访问仅支持一级引用支持多级指针(如int**)

六、const在指针和引用中的对比
  1. 指针的const修饰

    • 指向常量的指针(底层const)

      1. const int *p = &x; // 不能通过p修改x的值
      2. // *p = 20; // 错误
      3. p = &y; // 正确:可以指向其他变量
      复制代码
    • 常量指针(顶层const)

      1. int *const p = &x; // p的指向不可变
      2. *p = 20; // 正确:可以修改x的值
      3. // p = &y; // 错误
      复制代码
    • 指向常量的常量指针

      1. const int *const p = &x; // 既不能修改指向,也不能修改值
      复制代码
  2. 引用的const修饰

    • 常引用只能绑定到目标,且不能通过引用修改目标。

  1. const int &cref = x;
  2. // cref = 20; // 错误
  3. x = 20; // 正确
复制代码

七、常见错误与注意事项
  1. 返回局部变量的引用
    导致悬空引用,引发未定义行为。

    1. int& func() {
    2. int x = 10;
    3. return x; // 错误:x在函数结束后销毁
    4. }
    复制代码
  2. 类型不匹配的引用
    引用类型必须与目标变量类型严格一致。

    1. double a = 10.3;
    2. int &b = a; // 错误:类型不匹配
    复制代码
  3. 修改常引用
    尝试通过常引用修改目标变量会编译报错。

    1. const int &cref = x;
    2. cref = 20; // 错误:assignment of read-only reference
    复制代码
  4. 引用与指针的混淆
    引用不是指针,不能进行指针的运算(如++、--)。

  5.  重中之重:
  • 指针在程序运行的时候,可以改变它的值,而引用和一个变量绑定之后就不能在引用其他变量
  • ”sizeof(引用)” 得到的是所指向的变量(对象)的大小,而 ”sizeof(指针)” 得到的是指针本身的大小;
  • 理论上,对于指针的级数没有限制,但是引用只能是一级
  • 引用的本质是指针,但它在语义和使用上与指针有所不同。
  • 引用不能是空的,它必须始终引用一个有效的对象。
  • 指针可以是空的,并且可以在其生命周期内改变指向。

函数基本介绍

一、编译器对函数名的处理
  1. C 编译器

    • 函数名不变:编译后的函数名与源代码中的名称完全一致。

    • 示例:函数 add 在汇编代码中仍为 add。

    • 不支持函数重载:同名函数无法通过参数列表区分。

  2. C++ 编译器

    • 名称修饰(Name Mangling):将函数名与参数类型结合,生成唯一标识符。

      • 示例

        • int add(int a, int b) → _Z3addii

        • float add(float a, float b) → _Z3addff

    • 支持函数重载:通过不同参数列表生成不同修饰名,确保链接器正确区分函数。

二、函数重载(Function Overloading)
  1. 定义

    • 在同一作用域内,允许定义多个同名函数,但要求 参数列表不同(参数类型或数量不同)。

    • 示例

  1. int add(int a, int b); // 两个 int 参数
  2. int add(int a, int b, int c); // 三个 int 参数
  3. float add(float a, float b); // 两个 float 参数
复制代码
  1. 本质

    • 通过名称修饰实现,不同参数列表生成不同的内部函数名。

    • 编译后示例

      • _Z3addii、_Z3addiii、_Z3addff。

  2. 限制

    • 返回值类型不同不足以构成重载

    • 作用域必须相同:不同类或命名空间中的同名函数不构成重载。

三、默认参数(Default Arguments)
  1. 定义

    • 在函数声明时为参数提供默认值,调用时若未传递该参数,则使用默认值。

    • 示例

  1. int add(int a, int b, int c = 100); // c 的默认值为 100
复制代码

     2.规则

  • 默认参数必须从右向左连续设置

  1. int func(int a, int b = 10, int c = 20); // 正确
  2. int func(int a, int b = 10, int c); // 错误!c 无默认值
复制代码
  • 默认参数只能在声明中指定,定义时不可重复。

  • 调用时省略参数需按顺序

  1. add(10, 20); // 等效于 add(10, 20, 100)
复制代码
  1. 应用场景

    • 简化高频调用函数的参数传递。

    • 注意避免与函数重载的二义性冲突。

四、内联函数(Inline Functions)
  1. 背景

    • 普通函数调用的开销:压栈、跳转、返回等操作消耗时间和空间。

    • 优化目标:消除调用开销,提升短小且频繁调用函数的性能。

  2. 定义与使用

    • 使用 inline 关键字标记函数,建议编译器内联展开:

  1. inline int add(int a, int b) { return a + b; }
复制代码

        强制内联(GCC扩展)

  1. extern int add(int a, int b) __attribute__((always_inline));
复制代码
  1. 注意事项

    • 编译器决策权:inline 仅为建议,编译器可能拒绝内联复杂函数(如含循环或递归)。

    • 代码膨胀风险:过度内联会导致可执行文件体积增大,可能降低缓存效率。

    • 适用场景:适合简单、高频调用的函数(如数学运算、getter/setter)。

五、对比总结
特性C 语言C++ 语言
函数名处理无名称修饰名称修饰(支持重载)
函数重载不支持支持(参数列表不同即可)
默认参数不支持支持(需从右向左设置)
内联函数无原生支持(可通过宏模拟)支持(inline 关键字或编译器属性)
六、最佳实践
  1. 函数重载

    • 确保参数列表差异明确,避免仅通过返回值类型重载。

    • 优先使用参数类型差异而非默认参数实现重载。

  2. 默认参数

    • 默认参数声明放在头文件中,定义时不可重复默认值。

    • 避免默认参数与重载函数产生二义性。

  3. 内联函数

    • 仅对简单、高频调用的函数使用内联。

    • 谨慎使用强制内联属性(如 always_inline),需评估代码膨胀影响。

C++ 堆区内存管理总结与归纳


一、内存分配与释放机制对比
特性C语言 (malloc/free)C++ (new/delete)
类型标准库函数运算符
内存初始化分配原始内存,不调用构造函数分配内存并调用构造函数(初始化对象)
内存释放仅释放内存,不调用析构函数调用析构函数后释放内存
返回值void*,需手动类型转换返回对应类型指针,无需类型转换
内存大小计算需手动计算(如 malloc(sizeof(int) * n)自动计算类型大小(如 new int[n])
安全性易产生内存泄漏和类型错误类型安全,减少人为错误
适用场景与C代码兼容、简单内存分配面向对象编程,需构造/析构函数的场景
二、new 和 delete 的具体用法
  1. 单个对象的内存管理

    • 分配并初始化

  1. int* p = new int(10); // 分配内存并初始化为10
复制代码

              2.释放内存

  1. delete p; // 调用析构函数并释放内存
复制代码

对象数组的内存管理

  • 分配数组(C++11起支持显式初始化)

  1. int* arr = new int[3]{1, 2, 3}; // 分配3个int并初始化为1,2,3
复制代码
  • 释放数组
  1. delete[] arr; // 释放数组内存
复制代码

注意事项

  • 不可混用 new[] 与 delete:必须使用 delete[] 释放数组。

  • 避免显式计算数组长度

  1. int size = sizeof(p)/sizeof(p[0]); // 错误!指针无法计算数组长度
复制代码
三、malloc/free 与 new/delete 的区别
  1. 核心差异

    • 对象生命周期管理

      • new/delete 自动调用构造函数和析构函数,适用于对象。

      • malloc/free 仅操作原始内存,不涉及对象生命周期。

    • 类型安全

      • new 返回类型化指针,malloc 返回 void* 需手动转换。

    • 底层关系

      • new/delete 底层通过 malloc/free 实现,但添加了构造/析构逻辑。

  2. 为何C++保留 malloc/free?

    • 兼容C代码:C++需与C语言库和遗留代码兼容。

    • 低级内存操作:某些场景需直接操作原始内存(如自定义内存池)。

四、面试常见问题
  1. 为何C++引入 new/delete?

    • 支持对象构造和析构,确保资源管理安全。

    • 提供类型安全和更简洁的语法。

  2. new 初始化数组的限制(C++11前)

    • C++98不允许显式初始化动态数组,所有元素默认初始化。

    • C++11允许显式初始化(如 new int[3]{1,2,3})。

五、格式化输出内存数据
  1. 控制符说明

    控制符作用示例
    std::hex十六进制输出cout << hex << num;
    std::uppercase十六进制字母大写cout << uppercase << 0xff;
    std::setw(n)设置输出宽度为n位cout << setw(2) << num;
    std::setfill(ch)设置填充字符为chcout << setfill('0') << num;
    std::nouppercase恢复小写输出cout << nouppercase << 0xff;
  2. 输出 unsigned char 的陷阱

    • unsigned char 可能被当作字符输出(如 ASCII 码),需强制转换为 int:

  1. cout << static_cast<int>(buffer[i]);
复制代码

简单示例:

  1. #include <iostream>
  2. #include <iomanip>
  3. using namespace std;
  4. // 分配内存函数
  5. void allocate_memory(unsigned char* &buffer, int size) {
  6. buffer = new unsigned char[size];
  7. if (buffer == nullptr) {
  8. cerr << "内存分配失败!" << endl;
  9. exit(EXIT_FAILURE);
  10. }
  11. }
  12. // 写入数据函数
  13. void write_data(unsigned char* buffer, int size) {
  14. for (int i = 0; i < size; i++) {
  15. buffer[i] = static_cast<unsigned char>(0x11 * i);
  16. }
  17. }
  18. // 输出数据函数
  19. void print_data(unsigned char* buffer, int size) {
  20. cout << hex << uppercase << setfill('0');
  21. for (int i = 0; i < size; i++) {
  22. //cout << setw(2) << static_cast<int>(buffer[i]);
  23. cout << hex << setw(4) << setfill('0') << static_cast<int>(buffer[i]) ;
  24. cout<< " ";
  25. cout << hex << uppercase << setw(4) << setfill('0') << static_cast<int>(buffer[i])<< endl;
  26. if (i != size - 1) cout << " ";
  27. }
  28. cout << hex << nouppercase << setfill(' ') << endl;
  29. }
  30. int main() {
  31. const int SIZE = 10;
  32. unsigned char* buffer = nullptr;
  33. // 分配内存
  34. allocate_memory(buffer, SIZE);
  35. // 写入数据
  36. write_data(buffer, SIZE);
  37. // 输出数据
  38. print_data(buffer, SIZE);
  39. // 释放内存
  40. delete[] buffer;
  41. return 0;
  42. }
复制代码

C++ 调用 C 语言动态库


一、C++ 与 C 的函数名处理差异
  1. C 语言编译器

    • 无名称修饰:函数名在编译后保持原样(如 add → add)。

    • 不支持函数重载:同名函数无法通过参数列表区分。

  2. C++ 编译器

    • 名称修饰(Name Mangling):将函数名与参数类型结合生成唯一标识符(如 add(int, int) → _Z3addii)。

    • 支持函数重载:通过不同参数列表生成不同修饰名。


二、C++ 调用 C 动态库的链接问题
  1. 问题现象

    • 在 C++ 代码中直接调用 C 动态库函数时,链接器报错 undefined reference。

    • 原因:C++ 编译器期望函数名经过修饰,而 C 库中的函数名未修饰。

  2. 解决方案:extern "C"

    • 作用:告知 C++ 编译器按 C 语言规则处理函数名,避免名称修饰。

    • 语法:在 C 语言头文件中添加条件编译指令:

  1. #ifdef __cplusplus
  2. extern "C" {
  3. #endif
  4. extern int add(int, int);
  5. extern int sub(int, int);
  6. #ifdef __cplusplus
  7. }
  8. #endif
复制代码
  • 说明

    • __cplusplus 宏仅在 C++ 编译环境中定义。

    • C 编译器会忽略 extern "C" 声明,保持兼容性。

三、动态库的生成与使用

nm -D libas.so

  1. 编译时错误

    • undefined reference:未正确链接库或未使用 extern "C" 声明。

    • libas.so: cannot open shared object file:运行时未找到动态库,需设置 LD_LIBRARY_PATH。

  2. 验证动态库符号

    • 使用 nm 命令查看库中的符号列表:

  3. C 语言库中的符号应为原始函数名(如 add、sub),而非修饰后的名称。

  4. 生成 C 动态库

  1. # 编译为位置无关代码(-fPIC)
  2. // add.c和sub.c都作为示例代码
  3. gcc -fPIC -c add.c -o add.o
  4. gcc -fPIC -c sub.c -o sub.o
  5. # 生成动态库(-shared)
  6. gcc -shared -o libas.so add.o sub.o
复制代码

C++ 调用动态库

  • 编译命令

  1. g++ main.cpp -I ./ -L ./ -las
复制代码
    • -I ./:指定头文件路径。

    • -L ./:指定库文件路径。

    • -las:链接名为 libas.so 的库(-l 后跟库名,省略 lib 前缀和 .so 后缀)。

  • 编译时出现链接错误使用

    readelf -a a.out | grep "共享库" 

    确保编译时能找到库文件

  • 运行时路径设置

  1. export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:动态库路径
  2. ./a.out
复制代码

     运行时动态库未找使用

    ldd a.out

    若出现not found需要更改路径

    export LD_LIBRARY_PATH=动态库路径(pwd查找当前路径)

    确保运行时系统能找到动态库路径

    五、关键总结
    要点说明
    名称修饰差异C++ 通过名称修饰支持重载,C 无此机制。
    extern "C" 的作用避免 C++ 对 C 函数名进行修饰,确保链接正确。
    动态库生成与链接使用 -fPIC 和 -shared 生成动态库,-I、-L、-l 指定路径和库名。
    运行时库路径通过 LD_LIBRARY_PATH 设置动态库搜索路径。

    面向对象与面向过程


    一、核心区别
    维度面向过程(Procedure-Oriented)面向对象(Object-Oriented)
    核心思想将问题分解为一系列步骤,通过函数逐步实现。将问题抽象为对象,通过对象间的交互解决问题。
    关注点步骤逻辑:关注“怎么做”对象职责:关注“谁来做”
    典型场景简单、线性任务(如数学计算、脚本处理)复杂系统(如游戏、企业级应用)
    设计模式自顶向下,逐步细化自底向上,先定义对象再组合
    二、示例对比
    1. 将大象放进冰箱
    • 面向过程

      1. 打开冰箱

      2. 放入大象

      3. 关闭冰箱

    1. void putElephant() {
    2. openFridge();
    3. placeElephant();
    4. closeFridge();
    5. }
    复制代码

    面向对象

    1. 冰箱对象调用 open() 方法

    2. 冰箱对象调用 store(elephant) 方法

    3. 冰箱对象调用 close() 方法

    1. class Fridge {
    2. public:
    3. void open();
    4. void store(Object obj);
    5. void close();
    6. };
    7. Fridge fridge;
    8. fridge.open();
    9. fridge.store(elephant);
    10. fridge.close();
    复制代码
    2. 五子棋游戏
    • 面向过程

      • 按步骤实现:开始游戏 → 黑子走棋 → 绘制 → 判断输赢 → 白子走棋 → ...

      • 代码耦合度高,修改规则可能影响全局逻辑。

    • 面向对象

      • 对象划分

        • 玩家对象:处理输入,通知棋盘变化。

        • 棋盘对象:绘制棋盘,更新棋子状态。

        • 规则对象:判断输赢、犯规。

      • 优势:模块独立,修改规则仅需调整规则类。


    三、优缺点对比
    维度面向过程面向对象
    优点1. 设计简单,适合小型程序。
    2. 执行效率高。
    1. 易维护、易扩展。
    2. 代码复用性高。
    缺点1. 维护性差,逻辑耦合度高。
    2. 难以适应复杂需求。
    1. 设计复杂度高。
    2. 性能略低于面向过程。

    四、面向对象的核心特性
    1. 封装(Encapsulation)

      • 定义:将数据(属性)和方法(行为)绑定为一个独立的对象,隐藏内部实现细节。

      • 示例

    1. class Car {
    2. private:
    3. int speed; // 属性
    4. public:
    5. void accelerate() { speed += 10; } // 方法
    6. };
    复制代码

    继承(Inheritance)

    • 定义:子类继承父类的属性和方法,实现代码复用和层次化设计。

    • 示例

    1. class Animal {
    2. public:
    3. void eat() { ... }
    4. };
    5. class Dog : public Animal { ... }; // Dog 继承 Animal
    复制代码

    多态(Polymorphism)

    • 定义:同一操作作用于不同对象时,产生不同的行为。

    • 示例

    1. class Shape {
    2. public:
    3. virtual void draw() = 0; // 抽象方法
    4. };
    5. class Circle : public Shape {
    6. void draw() override { /* 绘制圆形 */ }
    7. };
    复制代码
    五、适用场景
    • 面向过程

      • 简单任务(如数学运算、脚本处理)。

      • 对性能要求极高的场景(如嵌入式开发)。

    • 面向对象

      • 复杂系统(如GUI应用、游戏开发)。

      • 需要长期维护和扩展的项目(如企业级软件)。


    六、总结
    核心思想适用场景核心特性开发效率 vs 运行效率
    面向过程简单、线性问题开发快,运行效率高
    面向对象复杂、模块化系统封装、继承、多态开发慢,运行效率略低

    总结

    • 面向过程以步骤为核心,适合简单、一次性任务;

    • 面向对象以对象为核心,通过封装、继承、多态提升代码的可维护性和扩展性,适合复杂系统。

    • 实际开发中,二者常结合使用(如面向对象框架内封装面向过程逻辑)。

    • 这是本人的学习笔记不是获利的工具,小作者会一直写下去,希望大家能多多监督我
    • 文章会每攒够两篇进行更新发布(受平台原因,也是希望能让更多的人看见)
    • 感谢各位的阅读希望我的文章会对诸君有所帮助

      本帖子中包含更多资源

      您需要 登录 才可以下载或查看,没有账号?立即注册

      ×
      您需要登录后才可以回帖 登录 | 立即注册

      本版积分规则

      中国红客联盟公众号

      联系站长QQ:5520533

      admin@chnhonker.com
      Copyright © 2001-2026 Discuz Team. Powered by Discuz! X3.5 ( 粤ICP备13060014号 )|天天打卡 本站已运行