C++函数知识点大全(四)

简介: 教程来源 https://xcfsr.cn/category/software-dev.html 本文系统讲解C++函数核心特性:虚函数与多态(含纯虚函数、虚析构)、虚函数表机制、异常处理(noexcept、异常安全设计)、以及函数最佳实践(const引用、移动语义、默认参数、单一职责等),涵盖从基础到高级的完整知识体系。

十、虚函数与多态

10.1 虚函数基础

#include <iostream>
using namespace std;

class Animal {
public:
    // 虚函数:支持动态绑定
    virtual void speak() {
        cout << "动物发出声音" << endl;
    }

    // 纯虚函数:抽象类
    virtual void move() = 0;

    // 虚析构函数
    virtual ~Animal() {
        cout << "Animal析构" << endl;
    }
};

class Dog : public Animal {
public:
    void speak() override {  // override显式标记重写
        cout << "汪汪汪" << endl;
    }

    void move() override {
        cout << "狗在跑" << endl;
    }

    ~Dog() override {
        cout << "Dog析构" << endl;
    }
};

class Cat : public Animal {
public:
    void speak() override {
        cout << "喵喵喵" << endl;
    }

    void move() override {
        cout << "猫在跳" << endl;
    }
};

int main() {
    // 多态使用
    Animal* ptr1 = new Dog();
    Animal* ptr2 = new Cat();

    ptr1->speak();  // 调用Dog的speak
    ptr1->move();   // 调用Dog的move
    ptr2->speak();  // 调用Cat的speak
    ptr2->move();   // 调用Cat的move

    delete ptr1;
    delete ptr2;

    return 0;
}

10.2 虚函数表

#include <iostream>
using namespace std;

class Base {
public:
    virtual void func1() { cout << "Base::func1" << endl; }
    virtual void func2() { cout << "Base::func2" << endl; }
    void func3() { cout << "Base::func3" << endl; }
};

class Derived : public Base {
public:
    void func1() override { cout << "Derived::func1" << endl; }
    virtual void func4() { cout << "Derived::func4" << endl; }
};

int main() {
    // 查看对象大小(虚函数表指针)
    cout << "sizeof(Base) = " << sizeof(Base) << endl;      // 8字节(64位系统)
    cout << "sizeof(Derived) = " << sizeof(Derived) << endl; // 8字节

    // 动态类型识别
    Base* ptr = new Derived();

    // typeid获取类型信息
    cout << "typeid(*ptr).name() = " << typeid(*ptr).name() << endl;

    // dynamic_cast向下转型
    Derived* dptr = dynamic_cast<Derived*>(ptr);
    if (dptr) {
        dptr->func4();
    }

    delete ptr;

    return 0;
}

十一、异常处理中的函数

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

// 可能抛出异常的函数
double divide(double a, double b) {
    if (b == 0) {
        throw invalid_argument("除数不能为零");
    }
    return a / b;
}

// 异常规范(C++11后已弃用)
// void func() throw(int, char);  // 可能抛出int或char
// void func() throw();           // 不抛出任何异常

// noexcept函数(C++11)
void safeFunc() noexcept {
    // 保证不抛出异常
    cout << "安全函数" << endl;
}

// 可能抛出异常的noexcept函数
void maybeThrow() noexcept(false) {
    throw runtime_error("可能抛出");
}

// 异常安全的函数设计
class SafeCalculator {
public:
    double divide(double a, double b) {
        if (b == 0) {
            throw invalid_argument("除数不能为零");
        }
        return a / b;
    }

    // 强异常安全保证
    void transfer(int from, int to, double amount) {
        double temp = getBalance(from);
        if (temp < amount) {
            throw runtime_error("余额不足");
        }
        // 先更新from
        setBalance(from, temp - amount);
        try {
            setBalance(to, getBalance(to) + amount);
        } catch (...) {
            // 发生异常时恢复from
            setBalance(from, temp);
            throw;
        }
    }

private:
    double getBalance(int account) { return 0; }
    void setBalance(int account, double amount) {}
};

int main() {
    try {
        double result = divide(10, 0);
        cout << "结果: " << result << endl;
    } catch (const invalid_argument& e) {
        cerr << "参数错误: " << e.what() << endl;
    } catch (const exception& e) {
        cerr << "异常: " << e.what() << endl;
    }

    safeFunc();

    try {
        maybeThrow();
    } catch (...) {
        cout << "捕获异常" << endl;
    }

    return 0;
}

十二、函数最佳实践

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

// 1. 使用const引用传递大对象
void processData(const vector<int>& data) {
    // 避免拷贝,使用const确保不修改
}

// 2. 返回局部对象时依赖RVO/NRVO
vector<int> createData() {
    vector<int> result;
    result.reserve(100);
    // 填充数据
    return result;  // 编译器会优化,不会拷贝
}

// 3. 使用移动语义
class Buffer {
private:
    unique_ptr<char[]> data;
    size_t size;

public:
    // 移动构造函数
    Buffer(Buffer&& other) noexcept
        : data(move(other.data)), size(other.size) {
        other.size = 0;
    }

    // 移动赋值
    Buffer& operator=(Buffer&& other) noexcept {
        if (this != &other) {
            data = move(other.data);
            size = other.size;
            other.size = 0;
        }
        return *this;
    }

    // 禁止拷贝
    Buffer(const Buffer&) = delete;
    Buffer& operator=(const Buffer&) = delete;
};

// 4. 使用默认参数简化接口
void log(const string& message, int level = 0, bool timestamp = true) {
    if (timestamp) {
        cout << "[TIME] ";
    }
    cout << string(level, ' ') << message << endl;
}

// 5. 使用noexcept提升性能
void swapNoexcept(int& a, int& b) noexcept {
    int temp = a;
    a = b;
    b = temp;
}

// 6. 使用inline建议编译器内联
inline int square(int x) noexcept {
    return x * x;
}

// 7. 函数设计原则:单一职责
// 不好
void processUser(string name, int age, string email) {
    // 验证、保存、发送邮件混在一起
}

// 好
bool validateUser(const string& name, int age, const string& email);
void saveUser(const string& name, int age, const string& email);
void sendWelcomeEmail(const string& email);

int main() {
    log("系统启动");
    log("用户登录", 1);
    log("错误", 2, true);

    int a = 10, b = 20;
    swapNoexcept(a, b);
    cout << "a=" << a << ", b=" << b << endl;

    cout << "square(5) = " << square(5) << endl;

    return 0;
}

C++函数体系在继承C语言函数特性的基础上,引入了众多强大的新特性:函数重载、默认参数、内联函数、Lambda表达式、函数对象、模板函数、虚函数等。这些特性使得C++函数设计更加灵活、高效和现代化。本文系统性地梳理了C++函数的核心知识点,从基础到高级,从面向对象到泛型编程,帮助开发者建立完整的知识体系。
来源:
https://xcfsr.cn/category/ai.html

相关文章
|
5月前
|
人工智能 网络协议 网络安全
2026阿里云OpenClaw/Clawdbot部署+集成iMessage指南:苹果生态AI助手搭建教程
2026年,OpenClaw(前身为Clawdbot、Moltbot)凭借轻量化容器化架构、灵活的跨平台集成能力,成为个人与小型团队打造专属AI助手的首选工具。其支持自然语言指令解析、多任务自动化执行、多终端同步响应的核心特性,完美适配苹果生态用户的办公与生活需求。iMessage作为苹果生态核心的即时通讯工具,覆盖iPhone、Mac、iPad全终端,具备端到端加密、无缝同步的优势,将两者深度对接,可实现“iMessage发指令、AI自动化执行、全终端收结果”的跨场景体验,无需切换APP,随时随地调用AI能力处理文档生成、数据查询、任务提醒等事务。
1350 18
|
3月前
|
存储 监控 算法
大模型应用:算力分层治理:基于大模型算力四层匹配体系的优化方案.72
本文剖析大模型算力困局,指出“加卡低效”的根源在于忽视计算、访存、调度三层算力的协同失衡。提出四层匹配体系(计算/存储/通信/业务层),通过精度适配、显存优化、通信算法选择及场景化调度等实操方法,实现算力精准治理,让硬件投入真正转化为落地效率。
367 9
|
3月前
|
Web App开发 安全 前端开发
基于钓鱼邮件的 DarkSword 攻击对 iOS 设备的威胁机理与防御体系研究
DarkSword是2026年3月曝光的iOS高级钓鱼攻击,利用WebKit与内核漏洞链,在iOS 18.4–18.7设备上实现无文件、静默式入侵,窃取敏感数据。本文剖析其攻击机理,提出含漏洞修补、邮件过滤、内存检测与应急响应的多层次防御方案,并提供可落地的代码实现。(239字)
568 5
|
3月前
|
监控 NoSQL Java
SpringBoot + Redis分布式锁深度剖析,性能暴涨的秘密全在这里
分布式锁是在分布式系统中协调多个节点对共享资源进行互斥访问的机制。当多个服务实例需要访问共享资源时,分布式锁能确保同一时刻只有一个实例可以执行关键代码段。
254 3
|
3月前
|
存储 SQL 数据挖掘
事实表是什么?事实表和维度表有什么区别?
数据仓库中,事实表存储可度量的业务数值(如销售额、订单量),字段少、行数巨多、高频更新;维度表则描述分析上下文(如时间、客户、产品属性),字段多、行数少、相对静态。二者通过主键-外键关联,构成星型模型,支撑多维分析与决策——本质即“度量”与“描述”的协同。
|
3月前
|
Ubuntu API C++
OpenClaw 阿里云、本地搭建,+Windows WSL+本地源码安装与自定义修改保姆级教程
2026年OpenClaw作为灵活的AI Agent平台,不仅支持阿里云规模化部署与本地轻量运行,还能通过Windows WSL(Windows Subsystem for Linux)实现源码级安装与自定义修改——这种方式特别适合开发者学习底层逻辑、按需拓展功能,而受OpenClaw启发的超轻量级版本nanobot(仅4000行代码),更是入门源码学习的最佳选择。
651 0
|
前端开发 PHP
ThinkPHP6,视图的安装及模板渲染和变量赋值 view::fetch() ,view::assgin() ,助手函数
本文介绍了ThinkPHP6中视图的安装和使用,包括通过`composer`安装`topthink/think-view`,使用`view::fetch()`进行模板渲染和变量赋值,以及使用`view::assign()`进行全局模板变量赋值。还提到了助手函数作为`view::fetch()`和`view::assign()`的封装组合,但效率较低。
ThinkPHP6,视图的安装及模板渲染和变量赋值 view::fetch() ,view::assgin() ,助手函数
|
NoSQL Java Redis
Redlock分布式锁高并发下有什么问题
Redlock分布式锁在高并发场景下可能面临的问题主要包括:网络延迟、时钟偏移、单点故障、宕机重启问题、脑裂问题以及效率低等。接下来,我将使用Java代码示例来说明其中一些问题。
577 12
|
数据库 C# 开发者
WPF开发者必读:揭秘ADO.NET与Entity Framework数据库交互秘籍,轻松实现企业级应用!
【8月更文挑战第31天】在现代软件开发中,WPF 与数据库的交互对于构建企业级应用至关重要。本文介绍了如何利用 ADO.NET 和 Entity Framework 在 WPF 应用中访问和操作数据库。ADO.NET 是 .NET Framework 中用于访问各类数据库(如 SQL Server、MySQL 等)的类库;Entity Framework 则是一种 ORM 框架,支持面向对象的数据操作。文章通过示例展示了如何在 WPF 应用中集成这两种技术,提高开发效率。
524 0