C/C++ 基础笔记(十)

本篇核心知识:预处理指令、宏定义、条件编译、文件包含、C++ 面向对象、类与对象、访问权限、成员函数、this 指针、const 成员、头文件管理、内联函数、封装特性


一、预处理指令(编译前执行)

概念

预处理指令以#开头,编译前执行,不生成机器码,只做文本替换、文件包含、条件控制。

特性
  1. 预处理时机:编译之前,语法检查之前,直接替换文本。

  2. 三大核心指令#define#include、条件编译。

(1)#define 宏定义

概念

用名字替换固定文本,分无参宏带参宏,仅替换、无类型、无语法检查。

特性
  • 无参宏:

    复制代码
    #define 宏名 替换内容
    • 纯文本替换,末尾不加分号

    • 可定义常量、关键字、代码片段。

  • 带参宏:

    复制代码
    #define 宏名(参数) 表达式
    • 仅替换,不是函数,无类型检查、执行更快。

    • 表达式建议加括号防优先级错误。

  • 多行宏 :末尾用\换行,不可空格。

  • 宏 undef#undef 宏名 取消宏定义。

代码示例
复制代码
// 无参宏
#define MAX 100
#define PI 3.14159
#define PRINT_HELLO cout << "Hello\n"
​
// 带参宏(加括号防错)
#define SQR(x) ((x)*(x))
#define MAX2(a,b) ((a)>(b)?(a):(b))
​
// 多行宏
#define PRINT_INFO() \
    cout << "姓名:张三\n"; \
    cout << "年龄:20\n"
​
int main() {
    int a = SQR(5);   // 替换为((5)*(5))
    PRINT_HELLO;
    PRINT_INFO();
    return 0;
}

(2)#include 文件包含

概念

将头文件内容完整复制到当前位置,实现代码复用。

特性
  • #include <文件名>:优先查系统库目录,用于系统头文件。

  • #include "文件名":先查当前项目目录,再查系统目录,用于自定义头文件。

  • 重复包含问题:同一头文件多次包含会报错,需加保护。

代码示例
复制代码
// 系统头文件
#include <iostream>
// 自定义头文件
#include "myhead.h"

(3)条件编译

概念

按条件选择性编译代码,常用于调试、版本控制、跨平台、防重复包含。

特性
  • #if / #elif / #else / #endif:按常量表达式判断。

  • #ifdef:如果宏已定义。

  • #ifndef:如果宏未定义。

  • #endif :结束条件块,必须配对

  • 防重复包含:

    复制代码
    #ifndef HEAD_H
    #define HEAD_H
    // 头文件内容
    #endif
    ​
    // 或简化:#pragma once(VS支持)
代码示例
复制代码
#define DEBUG
// 调试模式输出
#ifdef DEBUG
cout << "调试:变量值=" << 10 << endl;
#else
cout << "发布模式" << endl;
#endif
​
// 版本控制
#define VERSION 2
#if VERSION == 1
cout << "V1.0" << endl;
#elif VERSION == 2
cout << "V2.0" << endl;
#else
cout << "未知版本" << endl;
#endif

拓展:宏与函数区别

  • 宏:编译前替换、无类型、速度快、无栈开销、易出错。

  • 函数:编译后调用、有类型、有栈开销、安全、可调试。


二、C++ 面向对象(OOP)基础

概念

面向对象以类(模板)对象(实例) 为核心,将数据和行为封装,模拟现实实体,具备**封装、继承、多态(、抽象)**几大特性。

特性
  1. 面向对象 vs 面向过程

    • 面向过程:关注步骤、函数、流程,适合简单程序。

    • 面向对象:关注实体、属性、行为,适合复杂项目、易维护复用。

  2. 四大特性

    • 封装:隐藏内部细节,暴露安全接口,保证数据安全。

    • 继承:子类复用父类代码,扩展功能,减少冗余。

    • 多态:同一接口,不同实现,灵活扩展。

    • 抽象:提取核心属性 / 行为,忽略无关细节。

代码示例

复制代码
// 面向对象:定义人类(类)
class Person {
    // 属性:成员变量(私有)
    char name[20];
    int age;
public:
    // 行为:成员函数(公有)
    void init(const char* n, int a) {
        strcpy(name, n);
        age = a;
    }
    void show() {
        cout << "姓名:" << name << ",年龄:" << age << endl;
    }
};
​
// 创建对象(实例)
int main() {
    Person p1;
    p1.init("张三", 20);
    p1.show();
    return 0;
}

三、类的定义与结构

概念

类是自定义复合类型,描述一组对象共同的属性和行为。

特性
  1. 类的组成

    • 成员变量(属性):描述对象状态。

    • 成员函数(行为):描述对象操作。

    • 访问权限:控制成员访问范围。

  2. 定义格式

    复制代码
    class 类名 {
        // 访问权限
        成员变量;
        成员函数声明;
    }; // 末尾必须加分号
  3. 对象定义类名 对象名;,分配独立内存。

代码示例

复制代码
// 类定义
class Student {
private:
    // 私有成员变量
    int id;
    double score;
public:
    // 成员函数声明
    void setInfo(int i, double s);
    void showInfo();
};

// 定义对象
Student s1, s2;

四、访问权限控制(封装核心)

概念

控制类成员的可见范围,实现数据隐藏、安全访问

特性
  1. public(公有):任意位置(类内、外、子类)可访问,用于接口。

  2. protected(保护):类内、子类可访问,外部不可,用于继承。

  3. private(私有):仅类内可访问,外部、子类不可,用于隐藏数据。

  4. 默认权限class默认 private,struct默认 public。

代码示例

复制代码
class Person {
private:
    int age; // 私有:外部不可直接访问
protected:
    char gender; // 保护:子类可访问
public:
    char name; // 公有:任意访问
    void setAge(int a) { age = a; } // 公有接口
};

int main() {
    Person p;
    p.name = "李四"; // 合法(公有)
    // p.age = 25; // 非法(私有)
    p.setAge(25); // 合法(通过接口)
    return 0;
}

拓展:权限设计原则

  • 数据成员默认 private,通过 public 接口访问修改,保证数据安全。

五、成员函数(定义与实现)

概念

类中描述对象行为的函数,分内部实现外部实现

特性
  1. 内部实现 :直接写在类内,默认内联函数,编译时展开,无调用开销。

  2. 外部实现:类内声明、类外定义,需加

    作用域符::,格式:返回值 类名::函数名(参数) { 函数体 }

  3. 内联函数inline修饰,空间换时间,适合短小高频函数。

代码示例

复制代码
class Student {
private:
    int id;
public:
    // 内部实现(默认内联)
    inline void setId(int i) { id = i; }
    // 外部声明
    void showId();
};

// 外部实现(加::)
void Student::showId() {
    cout << "学号:" << id << endl;
}

拓展:内联函数注意

  • 禁止递归、复杂循环,编译器可能忽略inline

六、this 指针

概念

类成员函数的隐藏常量指针,指向当前调用对象,区分不同对象成员。

特性
  1. 类型类名* const指向不可改,值可改。

  2. 作用:

    • 区分成员变量与局部 / 形参(同名冲突)。

    • 返回当前对象(链式调用)。

  3. 使用this->成员名访问成员。

代码示例

复制代码
class Person {
private:
    int age;
public:
    void setAge(int age) {
        // this->age:成员变量;age:形参
        this->age = age;
    }
    Person& getSelf() {
        return *this; // 返回当前对象
    }
};

拓展:this 不能用于静态成员函数(无对象)


七、const 成员(只读保护)

概念

const修饰成员变量、成员函数、对象,禁止修改,保证数据只读。

特性
  1. const 成员变量 :类内只读,必须初始化(构造函数初始化列表)。

  2. const 成员函数:

    • 格式:返回值 函数名() const

    • 禁止修改成员变量,只能调用 const 函数

  3. const 对象const 类名 对象只能调用 const 成员函数,不可调用非 const 成员函数

  4. 普通对象(无 const) :既能调用 普通函数,也能调用 const 成员函数,优先调用非 const 版本。

代码示例

复制代码
class Test {
public:
    int num = 10;

    // const 成员函数
    void show() const {
        cout << "const 函数:" << num << endl;
    }

    // 非 const 成员函数
    void show() {
        cout << "非 const 函数:" << num << endl;
    }
};

int main() {
    // 1. 普通对象(无const)
    Test obj;
    obj.show();   //  调用 非const 函数
    obj.show();   //  也能调用 const 函数(普通对象全能调用)

    // 2. const 对象
    const Test cobj;
    cobj.show();  //  只能调用 const 函数
    //cobj.show();//  不能调用 非const 函数
}

拓展:const 修饰指针 / 引用

  • const int*:指向常量,值不可改。

  • int* const:指针常量,指向不可改。


八、头文件与源文件分离

概念

大型项目中,类声明放.h头文件,实现放.cpp源文件,便于管理、复用、编译

特性
  1. 头文件(.h) :类声明、函数声明、宏、全局声明,只声明不定义

  2. 源文件(.cpp):类实现、函数定义、全局定义。

  3. 头文件保护 :防止重复包含,用#ifndef...#endif#pragma once

代码示例

复制代码
// Person.h(头文件)
#pragma once
class Person {
private:
    char name[20];
public:
    void setName(const char* n);
    void showName() const;
};

// Person.cpp(源文件)
#include "Person.h"
#include <cstring>
void Person::setName(const char* n) { // 声明外部实现
    strcpy(name, n);
}
void Person::showName() const {
    cout << "姓名:" << name << endl;
}

// main.cpp
#include "Person.h"
int main() {
    Person p;
    p.setName("XXX");
    p.showName();
    return 0;
}

九、结构体 vs 类(对比)

概念

结构体(struct)和类(class)都是复合类型,默认权限不同

特性
  • struct :默认public,仅数据,早期 C 风格。

  • class :默认private,数据 + 函数,面向对象。

  • 本质:C++ 中 struct 可写成员函数,与 class 语法一致。

代码示例

复制代码
// struct:默认public
struct Stu {
    int id;
    void show() { cout << id; }
};

// class:默认private
class StuC {
    int id;
public:
    void show() { cout << id; }
};
相关推荐
Frank学习路上1 小时前
【C++】面试:指针与引用
c++·面试
hanlin031 小时前
基于OpenHarmony 5.0的CAN驱动移植步骤
linux·c语言·华为·can·openharmony·t527
YIN_尹1 小时前
【Linux系统编程】基础IO第一讲——系统文件IO
android·java·linux·c++
聆风吟º1 小时前
【C标准库】深入理解C语言 atoi 函数:字符串转换为整数
c语言·开发语言·库函数·atoi
casual~1 小时前
【学习记录(2)】
c++·学习
苏宸啊10 小时前
IPC管道
linux·c++
BestOrNothing_201510 小时前
ROS2 话题通信实战:消息对象、Publisher 发布器与 Subscriber 订阅器保姆级教程
c++·ros2·subscriber·publisher·话题通信
三品吉他手会点灯11 小时前
C语言学习笔记 - 44.运算符和表达式 - 运算符2 - 除法与取余运算符
c语言·开发语言·笔记·算法
kkeeper~11 小时前
0基础C语言积跬步之动态内存管理
c语言·开发语言