云计算百科
云计算领域专业知识百科平台

C++ 基础核心知识

C++ 基础核心知识

C++作为一门兼具高效性和灵活性的编程语言,是系统开发、游戏引擎、嵌入式编程等领域的核心工具。本文将从变量类型、指针与引用、核心关键字、数据类型、宏与高级修饰符、函数指针等高频基础知识点入手,夯实编程基础。

一、变量的三类核心形态:局部、静态局部、全局

变量是程序存储数据的基本单元,根据作用域、生命周期和存储位置的差异,可分为局部变量、静态局部变量和全局变量三类,其特性和使用场景各有侧重,是理解C++内存管理的基础。

1. 核心特性对比

分类作用域生命周期初始化行为存储位置核心特点
局部变量 当前函数/代码块内 函数调用时创建,返回时销毁 未赋值则值随机 栈区(stack) 存取速度快,随用随弃,无内存泄漏风险
静态局部变量 当前函数内部(外部不可访问) 程序启动至结束 仅初始化一次,默认值0 数据段/BSS段 保留上次调用结果,函数内的“全局状态”
全局变量 整个程序内 程序启动至结束 默认初始化为0 数据段/BSS段 跨函数/文件共享,易导致程序耦合度升高

2. 实用场景解析

  • 局部变量:最常用的变量类型,适合存储临时数据,比如循环计数器、函数内部的中间计算结果。例如遍历数组时的索引变量int i,函数内临时存储计算值的int temp,用完自动释放栈内存,使用安全且无冗余开销。
  • 静态局部变量:适合需要“记忆状态”的场景,比如统计函数调用次数、递归深度控制、单例模式的懒汉式实现。例如:

void countCall() {
static int count = 0; // 仅首次调用初始化,后续调用保留值
cout << "调用次数:" << ++count << endl;
}
// 多次调用依次输出1、2、3…

  • 全局变量:用于存储整个程序需共享的全局数据,比如系统配置信息、全局缓冲区、跨模块的状态标识。但需谨慎使用,过多全局变量会导致程序耦合度升高、难以维护和调试;使用时可添加清晰注释,必要时用static修饰限制在当前文件内,避免跨文件命名冲突。

二、指针与引用:C++的核心内存操作符

指针和引用是C++区别于其他高级语言的核心特性,二者均用于间接操作变量,实现内存的灵活访问,但在语法、本质、功能和使用场景上差异显著,正确区分是避免内存错误的关键。

1. 核心区别总结

特性指针引用
本质 存储变量内存地址的独立变量,有自己的内存空间 变量的别名,无独立内存空间,与绑定对象共享地址
初始化 可延迟初始化,可设为nullptr(空指针) 必须在定义时初始化,且不能绑定空值/无效对象
重新绑定 可随时重新指向其他同类型对象 一旦绑定对象,生命周期内不可修改绑定关系
操作方式 需通过解引用符(*)访问目标值,指针移动用-> 直接操作,无需解引用,语法与普通变量一致
内存占用 32位系统4字节,64位系统8字节(与地址长度一致) 无额外内存占用,编译期处理,与绑定对象大小一致
安全性 可能出现野指针/悬空指针,使用前必须判空 无空引用,只要绑定有效对象则使用安全,无需判空
支持操作 可进行指针算术运算(如p++)、多级指针(int**) 不支持算术运算,无多级引用

2. 适用场景

  • 指针的适用场景:

    • 动态内存分配(new/delete):例如创建动态数组int* arr = new int[10]、自定义类的动态对象;
    • 遍历复杂数据结构(链表、树、图):通过指针移动访问下一个节点node->next,实现灵活的内存遍历;
    • 处理可选参数:允许传递nullptr表示“无参数”,适配多场景函数调用;
    • 多级间接访问:如指针的指针int** p,适用于二维数组、函数内修改外部指针;
    • 函数返回多个值:通过指针将结果输出到函数外部。
  • 引用的适用场景:

    • 函数参数传递:尤其是大型对象(如自定义类实例、std::string、std::vector),避免拷贝开销,提升程序效率。例如void printString(const string& s),直接引用原对象而非创建拷贝;
    • 函数返回值优化:实现链式调用(如cout << a << b,operator<<返回ostream&),避免返回值拷贝;
    • 类成员引用:必须在构造函数初始化列表中绑定,确保引用的生命周期与类对象一致,适用于类的关联属性;
    • 替代指针简化代码:在无需重新绑定的场景下,用引用替代指针,让代码更简洁、安全。

3. 核心注意事项

  • 指针使用前必须判空(if (p != nullptr)),避免野指针(未初始化)、悬空指针(指向已释放内存)导致程序崩溃;
  • 引用不能绑定临时变量(如int& a = 10;非法),除非是const引用(const int& a = 10;合法,编译器会创建临时对象);
  • 动态内存分配的指针需手动释放(delete/delete[]),否则会造成内存泄漏;建议优先使用智能指针(std::unique_ptr/std::shared_ptr)替代裸指针。

三、核心关键字

C++的关键字是控制程序语法规则、内存行为、访问权限的核心,其中const、static是最常用且易混淆的基础关键字,掌握其不同场景的语义,是编写规范、高效C++代码的前提。

1. const:常量修饰符,保证只读特性

const的核心语义是只读,可修饰变量、指针、引用、成员函数、函数参数等,是保证程序安全性、防止意外修改的重要工具,其修饰对象不同,语义也略有差异。

  • 修饰普通变量:const int max = 100,变量值初始化后不可修改,必须在定义时初始化;
  • 修饰指针:分为两种场景,核心看const与*的位置:
    • 指针常量(int* const p):const修饰指针本身,指针的指向不可修改,但指向的值可修改;
    • 指向常量的指针(const int* p):const修饰指向的值,值不可修改,但指针的指向可修改;
  • 修饰引用:const int& ref,引用的对象为只读,防止通过引用修改原对象,是函数参数传递的常用方式;
  • 修饰类成员函数:void show() const,函数后加const,表示该函数不修改类的任何非静态成员变量,是类的常成员函数;
  • 修饰函数参数:void func(const int& x),防止函数内部修改传入的参数值,同时避免拷贝开销。

2. static:静态修饰符,控制生命周期与作用域

static主要用于控制变量/函数的生命周期、作用域和访问权限,在不同场景下作用不同,核心分为“全局/函数内”和“类内”两大使用场景。

  • 静态局部变量(函数内):延长生命周期至程序结束,作用域仍限于当前函数内,仅初始化一次;
  • 静态全局变量/函数(文件内):将作用域限制在当前文件内,实现“文件私有”,避免跨文件命名冲突;函数默认具有外部链接属性,加static后变为内部链接;
  • 类的静态成员变量:属于类而非某个对象,所有类实例共享同一份数据,需在类外单独初始化(int ClassName::var = 0),存储在数据段;
  • 类的静态成员函数:属于类而非对象,无隐式的this指针,只能访问类的静态成员(变量/函数),可通过类名直接调用(ClassName::func()),无需创建对象。

3. new/delete 与 malloc/free:内存管理核心对比

new/delete是C++原生的内存操作运算符,malloc/free是C标准库的内存管理函数,二者均用于动态内存分配,但在语法、功能、特性上差异显著,C++开发中优先使用new/delete替代malloc/free。

特性new/deletemalloc/free
本质 C++语言原生运算符,属于语法层面 C标准库普通函数,需引入头文件<cstdlib>
内存计算 自动计算所需内存大小,无需手动指定 需开发者手动计算并传入内存字节数(如malloc(4*10))
初始化/析构 new调用对象构造函数完成初始化,delete调用析构函数释放资源 仅分配/释放原始内存,不调用构造/析构函数,内存内容为随机值
返回值类型 带类型的指针,无需强制类型转换(如int* p = new int) 返回void*类型指针,必须强制类型转换后使用(如int* p = (int*)malloc(4))
失败处理 分配失败时抛出bad_alloc异常,可通过try-catch捕获 分配失败时返回NULL,需手动判空检查
重载支持 可自定义重载,实现自定义内存池、内存分配策略 不可重载,分配策略固定
数组处理 有专门的数组版本new[]/delete[],匹配数组的构造/析构 无专门数组版本,需手动计算数组总字节数,且不处理数组对象的析构
类对象支持 完美支持类对象的动态创建/释放,是C++面向对象的核心支撑 仅能分配类对象的内存空间,无法初始化对象,不支持面向对象开发
示例 单个对象:int* p = new int(10); delete p;数组:int* arr = new int[5]; delete[] arr;类对象:Test* t = new Test(); delete t; 单个变量:int* p = (int*)malloc(4); free(p);数组:int* arr = (int*)malloc(4*5); free(arr);

4. 其他基础常用关键字对比

关键字/语法本质特性示例
typedef 编译阶段的类型别名定义 有类型检查,提升代码可读性,支持自定义复杂类型 typedef int MyInt; typedef vector<int> IntVec;
nullptr C++11空指针关键字 类型安全,仅能隐式转换为指针类型,无二义性 int* p = nullptr;
NULL 宏定义(通常为0或(void*)0) 可转换为整数类型,可能引发函数调用二义性 int* p = NULL;

使用建议:C++开发中优先使用new/delete替代malloc/free,优先使用nullptr替代NULL,避免类型二义性和内存管理错误。

四、数据类型与强制类型转换

C++是强类型语言,数据类型决定了变量的内存大小、取值范围和可执行操作;强制类型转换用于实现不同类型间的转换,C++提供了类型安全的转换运算符,替代C语言的隐式转换,明确转换意图。

1. 基本数据类型

C++的基本数据类型分为整型、浮点型、字符型、布尔型,其中整型遵循**“最小长度规则”**,具体长度可通过sizeof运算符查询,不同平台可能略有差异,核心类型如下:

  • 整型:short(至少16位/2字节)、int(至少与short等长,通常32位/4字节)、long(至少32位/4字节)、long long(至少64位/8字节);
  • 无符号整型:在整型前加unsigned,如unsigned int、unsigned long,不存储负数,最大值为对应有符号整型的2倍,适合存储计数类、索引类数据;
  • 浮点型:float(单精度,4字节)、double(双精度,8字节)、long double(扩展精度,≥8字节),用于存储小数,双精度是开发中的默认选择;
  • 字符型:char(1字节)、wchar_t(宽字符,2/4字节),用于存储单个字符,char可分为有符号(默认)和无符号(unsigned char);
  • 布尔型:bool,取值为true(1)或false(0),用于逻辑判断。

注意:可通过<climits>、<cfloat>头文件查看不同数据类型的取值范围,如INT_MAX(int的最大值)、FLT_MAX(float的最大值)。

2. 强制类型转换

C++提供4种类型安全的强制转换运算符,替代C语言的(类型)变量隐式转换,明确转换意图,减少转换错误,不同运算符适用于不同场景,不可混用。

转换运算符适用场景特性安全性
static_cast 基本类型转换、上行转换(派生类→基类)、非const转非const 编译期检查,无运行时类型检查 较高(需开发者保证转换合理性)
dynamic_cast 含虚函数的类层次结构转换,主要用于下行转换(基类→派生类) 运行期类型检查,基于RTTI(运行时类型信息) 最高(转换失败返回nullptr/抛出异常)
reinterpret_cast 任意指针/引用之间的转换、指针与整数的转换 编译期处理,仅做二进制位拷贝,不改变数据 最低(平台移植性差,慎用)
const_cast 移除变量的const或volatile属性 仅作用于指针/引用,不能直接修饰变量 中等(不可修改原常量值,否则行为未定义)

示例:

// static_cast:基本类型转换
int a = 10;
double b = static_cast<double>(a) / 3; // 3.33333

// dynamic_cast:类层次转换
class Base { virtual void func() {} };
class Derived : public Base {};
Base* p = new Derived;
Derived* d = dynamic_cast<Derived*>(p); // 转换成功

// const_cast:移除const属性
const int c = 20;
int* pc = const_cast<int*>(&c);
// *pc = 30; // 非法:修改原常量,行为未定义

// reinterpret_cast:指针类型强制转换
int x = 100;
int* px = &x;
char* pc = reinterpret_cast<char*>(px);

五、宏与高级修饰符:易混淆核心概念辨析

在C++开发中,#define宏、inline、constexpr、volatile、extern是高频易混淆的语法元素,其中#define是C语言兼容的预处理语法,其余均为C++的高级修饰符,掌握其差异是编写高效、安全代码的关键。

1. #define 与 inline:宏替换 vs 内联函数

二者均试图减少函数调用开销,但实现原理、阶段和安全性天差地别,inline是C++推荐的函数优化手段,优先用inline替代#define定义宏函数。

特性#define(宏)inline(内联函数)
处理阶段 预处理阶段(编译前),纯字符串替换 编译阶段,编译器做代码展开优化
类型检查 无任何类型检查,易因参数类型导致隐式错误 严格的参数/返回值类型检查,符合C++语法规则
作用域 全局有效,需用#undef手动终止作用域 遵循函数作用域,可受namespace/类限制
内存特性 无栈帧开销,但重复替换会增加代码段体积(代码膨胀) 无函数调用栈帧开销,编译器智能判断是否展开(复杂逻辑自动放弃内联)
支持特性 不支持递归、默认参数、函数重载 支持递归、默认参数、函数重载,与普通函数一致
坑点 缺少括号易出逻辑错误:#define MUL(a,b) a*b,调用MUL(2+3,4)展开为2+3*4=14(非预期20) 仅适用于短逻辑、高频调用的函数(如getter/简单计算),复杂函数内联无意义
示例 #define ADD(a,b) ((a)+(b))(加括号避免错误) inline int add(int a, int b) { return a + b; }

2. #define 与 const:宏常量 vs 常量变量

二者均用于定义“不可变值”,但const是C++强类型的常量修饰符,#define是无类型的预处理替换,生产环境优先使用const替代#define定义常量。

特性#define(宏常量)const(常量变量)
类型属性 无类型,仅做字符串替换,编译器无感知 有明确类型,编译器严格进行类型检查
处理阶段 预处理阶段直接替换,不参与编译过程 编译阶段处理,作为常量变量存入内存(数据段只读区域)
作用域 全局有效,跨文件可见,需#undef终止 局部const:作用域为代码块/函数;全局const:默认文件内私有(可通过extern扩展)
内存占用 不分配内存,编译时直接替换为字面量 分配内存,有唯一内存地址,可取址(&const_var)
类中使用 无法作为类成员(预处理阶段无类概念) 可作为类成员,非静态const需在构造函数初始化列表初始化,静态const需类外初始化
示例 #define PI 3.1415926 #define MAX_LEN 1024 const double PI = 3.1415926; const int MAX_LEN = 1024;

3. constexpr 与 const:编译期常量 vs 运行期只读变量

C++11引入constexpr,强化了“编译期常量”的语义,弥补了const“只读但未必是编译期常量”的缺陷,constexpr是更强的const。

特性const(只读变量)constexpr(编译期常量)
核心语义 初始化后值不可修改,值可运行期确定 值必须在编译阶段计算完成,运行期不可修改
初始化值 可接受编译期常量(如const int a=10)或运行期常量(如const int a=rand()) 必须是编译期可计算的常量表达式(字面量、constexpr变量、constexpr函数返回值)
内存占用 分配内存(数据段),有内存地址,可取址 编译期直接替换为字面量,通常不分配内存;若取址则分配只读内存
函数修饰 不可修饰函数,仅能修饰类成员函数为const 可修饰constexpr函数,要求函数体为编译期可执行的简单逻辑(无循环/动态内存)
类中使用 静态const成员需类外初始化;非静态const成员需构造函数初始化列表初始化 静态constexpr成员可直接在类内初始化(C++11及以上),无需类外定义
适用场景 定义运行期只读变量(函数内临时只读值、类实例的只读属性) 定义编译期确定的常量(数组大小、模板参数、编译期计算、硬件寄存器地址)
示例 const int a = rand();(合法,运行期常量) constexpr int a = 10+20; constexpr int arr[a];(标准合法,编译期确定数组大小)

4. volatile:易变变量修饰符,禁止编译器优化

volatile是C++中容易被忽略但至关重要的修饰符,核心语义是**“告诉编译器:该变量的值可能被程序外部因素修改,禁止对其进行任何优化”**,确保每次访问都直接读取内存,而非缓存到寄存器。

核心特性
  • 禁止编译器优化:编译器不会将volatile变量的值缓存到寄存器,每次读写都直接访问内存,避免优化导致的错误;
  • 不保证原子性:volatile仅保证内存可见性,不保证多线程下的操作原子性(如volatile int a++仍可能出现竞态条件,需配合互斥锁/原子操作);
  • 可与const结合:const volatile int a; 表示“变量值不可被本程序修改,但可能被外部修改,且每次访问都读内存”,适用于硬件寄存器操作;
  • 无传递性:volatile int* p,p是普通指针,*p是volatile值,修改p的指向不受限制。
  • 适用场景
    • 嵌入式开发:硬件寄存器操作(寄存器地址固定,值可能被硬件/外设修改);
    • 中断处理程序:中断服务函数中修改的变量,需防止编译器优化;
    • 多线程开发:多线程共享的变量,保证内存可见性(需配合内存屏障);
    • 信号处理函数:信号处理中修改的全局变量,避免编译器优化为死循环。
    示例

    // 嵌入式串口接收寄存器操作(寄存器地址固定,值由硬件修改)
    #define UART_RX_REG 0x12345678 // 串口接收寄存器物理地址
    volatile int* rx_reg = (volatile int*)UART_RX_REG;

    void read_uart_data() {
    while (*rx_reg == 0); // 循环等待寄存器值变化(禁止编译器优化为死循环)
    int data = *rx_reg; // 直接读取内存中的寄存器值,获取硬件数据
    }

    5. extern 与 static:作用域与链接属性控制(反向关键字)

    二者均用于控制变量/函数的链接属性和跨文件访问性,是C++模块化开发的核心修饰符,作用完全相反:extern实现跨文件共享,static实现文件/作用域私有。

    特性extern(外部链接)static(内部链接)
    核心作用 声明跨文件可见的变量/函数,指示编译器“去其他文件找定义” 限制变量/函数的作用域为当前文件,禁止跨文件访问,实现“文件私有”
    链接属性 外部链接:多个文件可共享同一变量/函数实体 内部链接:仅当前文件可见,其他文件可定义同名实体,互不影响
    变量修饰 1. extern int a;:仅声明,不分配内存;2. extern int a=10;:实际是定义,分配内存并初始化 1. 静态局部变量:延长生命周期至程序结束;2. 静态全局变量:文件内私有,默认初始化为0
    函数修饰 extern void func();:声明函数在其他文件定义(函数默认带extern,可省略) static void func();:函数文件内私有,其他文件无法调用
    类中使用 无直接作用(类成员按访问权限控制) 修饰类静态成员:所有对象共享,无this指针,类外初始化
    跨文件示例 // file1.cpp(定义)int g_val = 100;void show() { cout << g_val; }// file2.cpp(使用)extern int g_val;extern void show();show(); → 输出100 // file1.cppstatic int g_val = 100;static void show() { cout << g_val; }// file2.cppextern int g_val; → 编译错误(找不到定义)

    关键注意:全局变量/函数默认具有extern属性,若想限制为文件私有,需显式加static;extern仅作声明(除非初始化),不分配内存,避免重复定义。

    六、函数指针与指针函数

    函数指针和指针函数是C++中最易混淆的两个概念,二者语法仅差一对括号,但本质完全不同:函数指针是“指针”,指向函数;指针函数是“函数”,返回值为指针,是C++进阶开发的基础。

    1. 函数指针:指向函数的指针变量

    核心概念

    函数在内存中拥有唯一的入口地址,函数指针是一种特殊的指针变量,其值为函数的内存入口地址,通过函数指针可以间接调用函数,实现“函数的参数化传递”,是回调函数、策略模式的核心基础。

    函数指针的类型由函数的返回值和参数列表决定(与函数名无关),函数名本身就是函数的入口地址(如func等价于&func)。

    定义语法

    函数指针的定义需严格匹配目标函数的返回值类型和参数列表(类型+个数+顺序),括号不可省略(优先级问题),有两种定义方式:

    • 直接定义:返回值类型 (*函数指针名)(参数类型1, 参数类型2, …); 示例:int (*pFunc)(int, int); // 指向“接收两个int、返回int”的函数
    • 类型别名定义(推荐,简化复杂类型):typedef int (*FuncType)(int, int); // typedef方式
      using FuncType = int (*)(int, int); // C++11 using方式(更直观)
      FuncType pFunc; // 定义函数指针变量
    使用步骤与示例

    步骤:定义匹配的函数 → 将函数地址赋值给函数指针 → 通过函数指针间接调用函数(*可省略)。

    #include <iostream>
    using namespace std;

    // 1. 定义匹配的函数
    int add(int a, int b) { return a + b; }
    int sub(int a, int b) { return a b; }

    int main() {
    // 2. 定义函数指针并赋值(&可省略)
    int (*pFunc)(int, int) = add;

    // 3. 间接调用函数(两种方式等价,*可省略)
    cout << (*pFunc)(2, 3) << endl; // 标准写法,输出5
    cout << pFunc(5, 2) << endl; // 简化写法,输出3

    // 重新指向其他匹配函数
    pFunc = sub;
    cout << pFunc(5, 2) << endl; // 输出3

    return 0;
    }

    核心使用场景
    • 回调函数:操作完成后自动调用预先注册的函数,如C语言qsort的比较函数、异步操作的完成回调、框架钩子函数;
    • 策略模式:将不同业务逻辑封装为函数,通过函数指针动态选择执行策略,替代大量if-else/switch,提升代码灵活性;
    • 类的成员函数指针:类的非静态成员函数含隐式this指针,需指定类名定义:int (Math::*pMemFunc)(int, int) = &Math::add;(&不可省略);
    • 函数表/插件架构:通过函数指针数组存储多个同类型函数,实现动态函数调用,适用于插件、驱动开发。

    回调函数示例:

    #include <iostream>
    #include <cstdlib> // qsort头文件
    using namespace std;

    // 回调函数1:int升序比较
    int compare_asc(const void* a, const void* b) {
    return *(const int*)a *(const int*)b;
    }

    // 回调函数2:int降序比较
    int compare_desc(const void* a, const void* b) {
    return *(const int*)b *(const int*)a;
    }

    int main() {
    int arr[] = {3,1,4,2};
    int n = sizeof(arr)/sizeof(arr[0]);

    // qsort第四个参数是函数指针:动态传递比较策略
    qsort(arr, n, sizeof(int), compare_asc); // 升序排序
    for(int x : arr) cout << x << " "; // 1 2 3 4

    qsort(arr, n, sizeof(int), compare_desc); // 降序排序
    for(int x : arr) cout << x << " "; // 4 3 2 1

    return 0;
    }

    2. 指针函数:返回指针类型的函数

    核心概念

    指针函数是一种普通函数,其核心特征是返回值为指针类型,语法上无特殊修饰,仅需将返回值类型声明为指针即可,是动态内存分配、返回数组/对象地址的常用方式。

    定义语法

    返回值类型* 函数名(参数类型1, 参数类型2, …); 示例:int* createArr(int n); // 返回int类型指针的函数,接收一个int参数

    使用示例

    #include <iostream>
    using namespace std;

    // 指针函数:动态创建int数组,返回数组指针
    int* createArr(int n) {
    if (n <= 0) return nullptr;
    int* arr = new int[n]; // 动态分配堆内存
    for(int i=0; i<n; i++) {
    arr[i] = i * 2; // 初始化数组
    }
    return arr; // 返回堆内存指针
    }

    int main() {
    int* p = createArr(5);
    if (p != nullptr) {
    for(int i=0; i<5; i++) {
    cout << p[i] << " "; // 0 2 4 6 8
    }
    delete[] p; // 手动释放堆内存,避免泄漏
    p = nullptr;
    }
    return 0;
    }

    核心注意事项
    • 指针函数不能返回栈内存指针(如int* func() { int a; return &a; }),栈内存随函数调用结束销毁,返回后会成为悬空指针;
    • 若返回堆内存指针,调用者需手动释放内存(delete/delete[]),避免内存泄漏;
    • 指针函数的返回值可做链式访问,如node* getNext(node* p) { return p->next; },可连续调用getNext(getNext(p))。

    3. 函数指针与指针函数核心对比

    特性函数指针(指针)指针函数(函数)
    本质 特殊的指针变量,指向函数的入口地址 普通的函数,返回值为指针类型
    核心语法 括号不可省略:int (*p)(int, int) 无额外括号:int* f(int, int)
    优先级关键 (*p)提升*优先级,先表示指针,再关联函数 函数调用符()优先级高于*,先表示函数,再关联返回值指针
    内存存储 存储在栈区/数据段(指针变量),值为函数代码段地址 本身是函数代码段,返回值是指向栈/堆/数据段的指针
    核心用途 回调函数、策略模式、动态函数调用、插件架构 动态内存分配、返回数组/对象地址、链式访问
    易混点 省略括号则变为指针函数:int *p(int, int) 加括号则语法错误:int* (f)(int, int)(函数名不能被括号包裹)

    记忆技巧:看括号和*的结合关系——(*名)是函数指针(名是指针),类型* 名()是指针函数(名是函数)。

    七、结构体与类:C++面向对象的基础载体

    struct和class是C++实现面向对象编程的核心载体,二者功能几乎完全一致,仅默认访问权限和默认继承方式不同,适用于不同的编程场景。

    1. 核心区别

    特性structclass
    默认访问权限 public(公有):成员可直接被外部访问 private(私有):成员不可被外部访问,需通过公有接口访问
    默认继承方式 公有继承(public):基类的公有/保护成员在派生类中保持原有权限 私有继承(private):基类的公有/保护成员在派生类中变为私有
    核心设计意图 侧重组织数据,实现数据的聚合,偏向面向过程编程 侧重封装数据与操作,实现属性和方法的绑定,偏向面向对象编程
    适用场景 存储简单的纯数据结构(如坐标、学生信息、配置参数) 实现复杂的业务逻辑,封装属性和方法,支持继承、多态等面向对象特性

    2. 实用示例

    #include <iostream>
    #include <string>
    using namespace std;

    // struct:纯数据结构,默认public,仅存储数据
    struct Student {
    string name; // 公有成员,可直接访问
    int age;
    float score;
    };

    // class:封装数据与操作,默认private,通过公有接口访问
    class Calculator {
    private: // 默认private,外部不可访问
    int result; // 私有属性,仅类内可修改
    public:
    // 构造函数:初始化属性
    Calculator() : result(0) {}
    // 公有方法:提供外部访问接口
    void add(int num) { result += num; }
    void sub(int num) { result -= num; }
    int getResult() const { return result; } // const成员函数,不修改属性
    };

    int main() {
    // struct使用:直接访问成员
    Student s = {"张三", 18, 95.5};
    cout << "姓名:" << s.name << " 年龄:" << s.age << endl;

    // class使用:通过公有接口访问
    Calculator cal;
    cal.add(10);
    cal.sub(3);
    cout << "计算结果:" << cal.getResult() << endl; // 7

    return 0;
    }

    注意:struct在C++中并非单纯的C语言结构体,也支持成员函数、构造函数、继承、多态等面向对象特性,仅默认规则与class不同;开发中可根据设计意图选择,无需严格区分。

    八、总结

    C++基础知识点核心围绕内存管理、类型安全、作用域控制、代码解耦四大核心思想展开,核心要点可归纳为:

  • 变量管理:掌握局部、静态局部、全局变量的生命周期和存储位置,理解栈区、数据段的内存特性,避免内存越界;
  • 内存操作:区分指针与引用的本质差异,合理使用指针实现动态内存管理,优先用引用简化代码、提升安全性,杜绝裸指针的内存泄漏;
  • 关键字使用:掌握const(只读)、static(作用域/生命周期)的多场景语义,掌握new/delete与malloc/free的核心差异,优先用constexpr(编译期常量)、inline(内联函数)替代#define,提升代码类型安全;
  • 类型转换:放弃C语言的隐式转换,使用C++的4种类型安全转换运算符,根据场景选择static_cast/dynamic_cast/const_cast/reinterpret_cast;
  • 特殊修饰符:volatile保证内存可见性(硬件/多线程),extern/static控制跨文件访问性,实现模块化开发;
  • 函数指针:掌握函数指针的定义和使用,理解其在回调函数、策略模式中的核心作用,区分函数指针与指针函数的语法差异;
  • 面向对象基础:理解struct与class的核心区别,掌握封装的基本思想,通过类的公有接口访问私有成员,保证代码的可维护性。
  • 赞(0)
    未经允许不得转载:网硕互联帮助中心 » C++ 基础核心知识
    分享到: 更多 (0)

    评论 抢沙发

    评论前必须登录!