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

相关文章
|
6月前
|
人工智能 网络协议 网络安全
2026阿里云OpenClaw/Clawdbot部署+集成iMessage指南:苹果生态AI助手搭建教程
2026年,OpenClaw(前身为Clawdbot、Moltbot)凭借轻量化容器化架构、灵活的跨平台集成能力,成为个人与小型团队打造专属AI助手的首选工具。其支持自然语言指令解析、多任务自动化执行、多终端同步响应的核心特性,完美适配苹果生态用户的办公与生活需求。iMessage作为苹果生态核心的即时通讯工具,覆盖iPhone、Mac、iPad全终端,具备端到端加密、无缝同步的优势,将两者深度对接,可实现“iMessage发指令、AI自动化执行、全终端收结果”的跨场景体验,无需切换APP,随时随地调用AI能力处理文档生成、数据查询、任务提醒等事务。
1398 18
当用户需求不详细时,如何有效应对
当用户需求不详细时,如何有效应对
1338 0
|
存储 索引 Python
Python中的pop()方法:删除和提取列表元素的利器
概念: Python是一种功能强大的编程语言,拥有许多内置函数和方法来处理不同类型的数据结构。其中,列表(list)是一种常用的数据结构,用于存储和管理多个元素。而pop()方法则是Python列表中的一个重要方法,它能够删除并返回列表中指定索引位置的元素。
|
存储 域名解析 监控
「72变的云开发」serverless搭建几乎零成本的typecho博客
如果放在前些年,博客最好的方式是租用一台服务器,用来搭建博客。冗余的性能造成了浪费,想和文章达到同配置的服务器更为昂贵,而serverless真正做到了按量付费。
1355 0
「72变的云开发」serverless搭建几乎零成本的typecho博客
|
NoSQL Java Redis
Redlock分布式锁高并发下有什么问题
Redlock分布式锁在高并发场景下可能面临的问题主要包括:网络延迟、时钟偏移、单点故障、宕机重启问题、脑裂问题以及效率低等。接下来,我将使用Java代码示例来说明其中一些问题。
605 12
|
机器学习/深度学习 传感器 算法
【误码率仿真】基于QPSK+16QAM调制仿真(含误码率含Matlab代码
【误码率仿真】基于QPSK+16QAM调制仿真(含误码率含Matlab代码
1205 0
|
数据建模 5G
带你读《5G大规模天线增强技术》——2.4.2 天线设置
带你读《5G大规模天线增强技术》——2.4.2 天线设置
|
JSON fastjson 数据格式
com.alibaba.fastjson.JSONException: syntax error, expect {, actual [, pos 0
        在使用fastjson解析的时候遇到该错误,网上查找了半天,找到位大神的帖子是说解析的实体A中有实体B,在该条json中A实体只有一个,但B实体却有多个,导致解析出错,解决办法是在A实体中定义B实体时,定义为List,这个是大神当时遇到的错误。
10814 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() ,助手函数
|
数据库 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 应用中集成这两种技术,提高开发效率。
553 0

热门文章

最新文章