C++教程 第15章 多态
第15章 多态多态的概念与原理多态是面向对象编程的核心特性之一,它允许使用统一的接口处理不同类型的对象,实现”一个接口,多种实现”的设计理念。 多态的核心原理 接口与实现分离:通过抽象接口定义行为,具体实现由派生类提供 运行时绑定:调用哪个具体实现由对象的实际类型决定,而非声明类型 代码复用:统一的接口使得代码可以处理不同类型的对象 扩展性:新的派生类可以无缝集成到现有系统中 多态的类型C++支持两种类型的多态: 编译时多态(静态多态):在编译阶段确定调用哪个函数 函数重载 运算符重载 模板 运行时多态(动态多态):在运行阶段确定调用哪个函数 虚函数 纯虚函数 抽象类 运行时多态的实现虚函数核心特性:虚函数是在基类中声明并在派生类中重写的成员函数,通过虚函数表(vtable)实现运行时多态。 123456789101112131415161718192021222324252627282930313233343536373839class Base {public: virtual void doSomething() { ...
C++教程 第13章 面向对象设计
第13章 类与封装面向对象设计概述面向对象设计(Object-Oriented Design,OOD)是一种基于对象概念的软件开发方法,它通过抽象、封装、继承和多态等核心机制,将系统分解为相互协作的对象集合,每个对象封装了特定的职责和行为。 面向对象设计的核心原则 抽象(Abstraction):从具体实现中提取本质特征,形成抽象接口,隐藏实现细节 封装(Encapsulation):将数据和操作数据的方法绑定在一起,通过访问控制实现信息隐藏 继承(Inheritance):通过层次结构实现代码重用和类型扩展,建立”is-a”关系 多态(Polymorphism):通过统一接口支持不同实现,提高代码的灵活性和可扩展性 组合(Composition):通过对象组合实现更灵活的代码重用,建立”has-a”关系 面向对象设计的价值 可维护性:模块化设计和信息隐藏使得代码更易于理解和修改 可扩展性:通过继承和多态,系统可以在不修改现有代码的情况下进行扩展 可重用性:封装和抽象使得组件可以在不同场景中重复使用 可测试性:模块化设计使得单元测试更加容易实现 代码清晰度:面向对象的设计更符合...
C++教程 第16章 类的内存
第16章 类的内存类的内存布局类的内存布局是指类的成员变量和成员函数在内存中的存储方式。理解类的内存布局对于优化代码性能、理解对象模型和调试问题都非常重要。 基本概念 成员变量:存储在对象的内存空间中,每个对象都有自己的成员变量副本 成员函数:存储在代码段中,所有对象共享同一个成员函数副本 静态成员:存储在静态存储区中,所有对象共享同一个静态成员 虚函数表:存储在只读数据段中,包含虚函数的地址 虚指针:存储在对象的内存空间中,指向虚函数表 类的大小计算类的大小由以下因素决定: 成员变量的大小:所有非静态成员变量的大小之和 内存对齐:为了提高访问效率,编译器会对成员变量进行内存对齐 虚指针:如果类包含虚函数,会额外增加一个虚指针的大小 继承:派生类会包含基类的成员变量 12345678910111213141516171819202122232425262728// 空类的大小class EmptyClass { };// 一个空类的大小是1字节,而不是0字节// 这是为了确保每个对象都有唯一的内存地址std::cout << "Si...
C++教程 第18章 类的高级特性
第18章 类的高级特性友元友元函数友元函数是指可以访问类的私有成员和保护成员的非成员函数。 123456789101112131415161718192021222324252627282930313233#include <iostream>class Box {private: double width; double height; double depth; public: Box(double w, double h, double d) : width(w), height(h), depth(d) {} // 声明友元函数 friend double calculateVolume(const Box& box); friend void displayBox(const Box& box);};// 定义友元函数double calculateVolume(const Box& box) { return box.wi...
C++教程 第17章 类的内存管理
第17章 类的内存管理内存模型与存储类别内存分区与布局C++程序在运行时的内存空间可分为以下几个区域: 代码段(Text Segment):存储程序执行指令,通常为只读 只读数据段(RO Data Segment):存储常量、字符串字面量等 数据段(Data Segment):存储初始化的全局变量和静态变量 BSS段(Block Started by Symbol):存储未初始化的全局变量和静态变量,由系统自动初始化为0 堆(Heap):动态分配的内存区域,由程序员手动管理 栈(Stack):函数调用时的临时内存区域,自动分配和释放 存储类别与生命周期 存储类别 声明方式 存储位置 生命周期 作用域 自动存储 局部变量 栈 块作用域 块作用域 静态存储 static 数据段/BSS 程序生命周期 声明作用域 线程存储 thread_local 线程本地存储 线程生命周期 声明作用域 动态存储 new/delete 堆 手动管理 指针作用域 动态内存分配机制运算符底层实现1234567891011121314#include <...
C++教程 第19章 模板和泛型编程
第19章 模板和泛型编程模板的底层实现原理模板实例化机制模板是C++中实现泛型编程的核心机制,其底层实现涉及编译期实例化过程: 模板定义:编译器解析模板代码,但不生成具体代码 实例化触发:当模板被使用时(如创建对象或调用函数) 类型替换:编译器将模板参数替换为具体类型 代码生成:为每个唯一的模板实例生成专门的代码 优化:对生成的代码应用常规编译优化 模板实例化的编译器处理12345678910111213141516171819// 模板定义template <typename T>T maximum(T a, T b) { return a > b ? a : b;}// 实例化触发int main() { int a = 1, b = 2; double c = 1.5, d = 2.5; // 触发 int 版本的实例化 int max_int = maximum(a, b); // 触发 double 版本的实例化 double max_double = maxi...
C++教程 第20章 高级模板编程
第20章 高级模板编程模板的基本概念模板是C++中实现泛型编程的核心机制,它允许我们编写与类型无关的代码,提高代码的重用性和灵活性。 什么是模板?模板是一种参数化的代码蓝图,它可以根据不同的类型参数生成具体的代码。C++中的模板分为两种: 函数模板:生成不同类型的函数 类模板:生成不同类型的类 模板的优势 代码重用:编写一次代码,适用于多种类型 类型安全:在编译时进行类型检查 性能优化:编译器可以为特定类型生成优化的代码 灵活性:可以处理各种类型,包括自定义类型 函数模板函数模板是一种通用的函数定义,它可以操作不同类型的参数。 基本语法1234 template <typename T>T functionName(T parameters) { // 函数体} 其中,typename关键字可以替换为class,它们的含义相同。 示例:最大值函数1234567891011121314151617181920212223#include <iostream>// 函数模板:求两个值的最大值template<typena...
C++教程 第21章 运算符重载
第21章 运算符重载运算符重载的基本概念运算符重载是C++的一项强大特性,允许程序员为自定义类型定义运算符的行为。通过运算符重载,可以使自定义类型的使用更加直观和自然。 什么是运算符重载?运算符重载是指重新定义运算符的行为,使其能够应用于自定义类型。例如,我们可以为一个Complex(复数)类重载+运算符,使其能够直接进行复数加法运算。 运算符重载的语法运算符重载的语法与函数定义类似,只是函数名由operator关键字和要重载的运算符组成: 123返回类型 operator运算符(参数列表) { // 实现运算符的行为} 可重载的运算符C++中大部分运算符都可以重载,但有一些例外。以下是可重载和不可重载的运算符: 可重载的运算符 算术运算符:+, -, *, /, %, ++, -- 关系运算符:==, !=, <, >, <=, >= 逻辑运算符:&&, ||, ! 位运算符:&, |, ^, ~, <<, >> 赋值运算符:=, +=, -=, *=, /=, %=, &...
C++教程 第22章 函数对象与Lambda表达式
第22章 函数对象与Lambda表达式函数指针函数指针的概念函数指针是指向函数的指针,它可以存储函数的地址,并通过该地址调用函数。 函数指针的声明与使用12345678910111213// 声明函数指针int (*addPtr)(int, int);// 定义函数int add(int a, int b) { return a + b;}// 赋值addPtr = add;// 调用int result = addPtr(1, 2); // 结果为3 函数指针作为参数12345678910111213141516171819void process(int a, int b, int (*operation)(int, int)) { int result = operation(a, b); std::cout << "Result: " << result << std::endl;}int add(int a, int b) { return...
C++教程 第23章 异常处理
第23章 异常处理异常处理的基本概念异常是程序执行过程中发生的错误或特殊情况,例如除以零、数组越界、内存分配失败等。C++的异常处理机制允许我们捕获和处理这些异常,使程序能够更加健壮和可靠。 异常处理的三个关键字 try:定义可能抛出异常的代码块 catch:捕获并处理异常 throw:抛出异常 异常处理的基本语法123456789101112131415161718192021#include <iostream>#include <string>int divide(int numerator, int denominator) { if (denominator == 0) { throw std::string("Division by zero"); } return numerator / denominator;}int main() { try { int result = divide(10, 0); ...



