C++笔记之静态成员函数的使用场景

C++笔记之静态成员函数的使用场景

在这里插入图片描述

C++静态成员函数的核心特点是不与特定类实例相关,可通过类名直接调用,用于执行与类相关的操作而无需创建类对象。其主要用途是在类级别上共享功能,管理全局状态或提供工具函数。

code review!

文章目录

  • C++笔记之静态成员函数的使用场景
    • 1.共享数据:当类的所有实例需要共享某个数据时,可以使用静态数据成员
    • 2.工具函数: 静态函数成员通常用于实现与类相关的工具函数,这些函数不需要访问实例特定的数据
    • 3.计数或标识: 使用静态成员可以在所有实例之间保持计数或标识的状态
    • 4.单例模式: 静态成员可用于实现单例模式,确保一个类只有一个实例
    • 5.日志记录: 在一个应用程序中使用静态成员来记录和管理日志信息
    • 6.全局配置: 使用静态数据成员来保存全局配置设置
    • 7.数学常数: 在数学库中使用静态成员来提供常用的数学常数
    • 8.数据库连接池: 使用静态成员来管理共享的数据库连接池
    • 9.跟踪对象数量: 使用静态数据成员来跟踪特定类的实例数量
    • 10.全局事件处理: 使用静态函数成员来处理全局事件,如系统信号
    • 11.全局资源管理: 使用静态成员来管理全局资源,如文件句柄
    • 12.全局配置管理: 使用静态成员来加载和管理全局配置信息
    • 13.回调-事件处理:在事件驱动的程序中,可以使用静态回调函数来响应特定事件
    • 14.回调-异步回调:在异步编程中,可以使用静态回调函数来处理异步任务完成的通知
    • 15.回调-插件化架构: 在插件化架构中,可以使用静态回调函数来扩展和定制主程序的功能
    • 16.回调-回调集中管理: 使用静态回调函数集中管理程序中的不同事件和处理逻辑

1.共享数据:当类的所有实例需要共享某个数据时,可以使用静态数据成员

在这里插入图片描述

代码

class BankAccount {
private:
    static double interestRate; // 静态数据成员,所有账户共享利率
    double balance;
public:
    static void setInterestRate(double rate) {
        interestRate = rate;
    }
    // ...
};

// 在类外初始化静态数据成员
double BankAccount::interestRate = 0.05;

int main() {
    BankAccount::setInterestRate(0.07); // 所有账户的利率都被更新
    // ...
    return 0;
}

2.工具函数: 静态函数成员通常用于实现与类相关的工具函数,这些函数不需要访问实例特定的数据

在这里插入图片描述

代码

class MathUtils {
public:
    static int factorial(int n) {
        if (n <= 1)
            return 1;
        return n * factorial(n - 1);
    }
};

int main() {
    int fact = MathUtils::factorial(5); // 调用静态函数成员
    // ...
    return 0;
}

3.计数或标识: 使用静态成员可以在所有实例之间保持计数或标识的状态

在这里插入图片描述

代码

class Student {
private:
    static int count; // 静态数据成员,用于记录学生数量
    int studentID;
public:
    Student() {
        count++;
        studentID = count;
    }
    static int getCount() {
        return count;
    }
};

int Student::count = 0; // 初始化静态数据成员

int main() {
    Student s1, s2, s3;
    cout << "Total students: " << Student::getCount() << endl; // 输出学生数量
    // ...
    return 0;
}

4.单例模式: 静态成员可用于实现单例模式,确保一个类只有一个实例

在这里插入图片描述

代码

class Singleton {
private:
    static Singleton* instance; // 静态指针成员,指向单一实例
    Singleton() { /* 构造函数私有化,防止外部实例化 */ }
public:
    static Singleton* getInstance() {
        if (!instance)
            instance = new Singleton();
        return instance;
    }
    // ...
};

Singleton* Singleton::instance = nullptr; // 初始化静态指针成员为 nullptr

int main() {
    Singleton* singleton = Singleton::getInstance(); // 获取单例实例
    // ...
    return 0;
}

5.日志记录: 在一个应用程序中使用静态成员来记录和管理日志信息

在这里插入图片描述

代码

class Logger {
private:
    static std::ofstream logFile; // 静态文件流,用于日志记录
public:
    static void openLogFile(const std::string& filename) {
        logFile.open(filename);
    }
    static void log(const std::string& message) {
        if (logFile.is_open())
            logFile << message << std::endl;
    }
    static void closeLogFile() {
        logFile.close();
    }
};

std::ofstream Logger::logFile; // 初始化静态文件流

int main() {
    Logger::openLogFile("app.log");
    Logger::log("Application started.");
    // ...
    Logger::closeLogFile();
    return 0;
}

6.全局配置: 使用静态数据成员来保存全局配置设置

在这里插入图片描述

代码

class AppConfig {
private:
    static int maxConnections; // 最大连接数
public:
    static void setMaxConnections(int max) {
        maxConnections = max;
    }
    static int getMaxConnections() {
        return maxConnections;
    }
};

int AppConfig::maxConnections = 100; // 初始化最大连接数

int main() {
    AppConfig::setMaxConnections(150);
    int max = AppConfig::getMaxConnections();
    // ...
    return 0;
}

7.数学常数: 在数学库中使用静态成员来提供常用的数学常数

在这里插入图片描述

代码

class MathConstants {
public:
    static const double PI;
    static const double E;
};

const double MathConstants::PI = 3.141592653589793;
const double MathConstants::E = 2.718281828459045;

int main() {
    double circumference = 2 * MathConstants::PI * radius;
    // ...
    return 0;
}

8.数据库连接池: 使用静态成员来管理共享的数据库连接池

在这里插入图片描述

代码

class DBConnectionPool {
private:
    static std::vector<Connection> pool; // 静态连接池
public:
    static void initializePool(int size) {
        for (int i = 0; i < size; ++i) {
            pool.push_back(Connection());
        }
    }
    static Connection getConnection() {
        if (!pool.empty()) {
            Connection conn = pool.back();
            pool.pop_back();
            return conn;
        }
        throw std::runtime_error("Connection pool empty.");
    }
    static void releaseConnection(const Connection& conn) {
        pool.push_back(conn);
    }
};

std::vector<Connection> DBConnectionPool::pool; // 初始化静态连接池

int main() {
    DBConnectionPool::initializePool(10);
    Connection conn = DBConnectionPool::getConnection();
    // ...
    DBConnectionPool::releaseConnection(conn);
    return 0;
}

9.跟踪对象数量: 使用静态数据成员来跟踪特定类的实例数量

在这里插入图片描述

代码

class ObjectCounter {
private:
    static int count; // 静态计数器,跟踪对象数量
public:
    ObjectCounter() {
        count++;
    }
    ~ObjectCounter() {
        count--;
    }
    static int getCount() {
        return count;
    }
};

int ObjectCounter::count = 0; // 初始化静态计数器

int main() {
    ObjectCounter obj1, obj2, obj3;
    std::cout << "Total objects: " << ObjectCounter::getCount() << std::endl;
    // ...
    return 0;
}

10.全局事件处理: 使用静态函数成员来处理全局事件,如系统信号

在这里插入图片描述

代码

class EventHandler {
public:
    static void handleShutdownSignal() {
        // 处理关闭信号的逻辑
    }
    static void handleInterruptSignal() {
        // 处理中断信号的逻辑
    }
};

int main() {
    // 注册信号处理函数
    std::signal(SIGINT, EventHandler::handleInterruptSignal);
    std::signal(SIGTERM, EventHandler::handleShutdownSignal);
    // ...
    return 0;
}

11.全局资源管理: 使用静态成员来管理全局资源,如文件句柄

在这里插入图片描述

代码

class ResourceManager {
private:
    static std::vector<FileHandle> openFiles; // 静态文件句柄列表
public:
    static FileHandle openFile(const std::string& filename) {
        FileHandle handle = openFileInternally(filename);
        openFiles.push_back(handle);
        return handle;
    }
    // ...
};

std::vector<FileHandle> ResourceManager::openFiles; // 初始化文件句柄列表

int main() {
    FileHandle file = ResourceManager::openFile("data.txt");
    // ...
    return 0;
}

12.全局配置管理: 使用静态成员来加载和管理全局配置信息

在这里插入图片描述

代码

class AppConfig {
private:
    static AppConfig instance; // 单例实例
    std::map<std::string, std::string> configData;
    AppConfig() {
        // 从配置文件加载配置数据
    }
public:
    static AppConfig& getInstance() {
        return instance;
    }
    std::string getConfigValue(const std::string& key) {
        return configData[key];
    }
};

AppConfig AppConfig::instance; // 初始化单例实例

int main() {
    std::string value = AppConfig::getInstance().getConfigValue("max_connections");
    // ...
    return 0;
}

13.回调-事件处理:在事件驱动的程序中,可以使用静态回调函数来响应特定事件

在这里插入图片描述

代码

class EventHandler {
public:
    static void onButtonClicked() {
        // 处理按钮点击事件的逻辑
    }
    static void onTextChanged(const std::string& newText) {
        // 处理文本变化事件的逻辑
    }
};

int main() {
    Button button;
    button.setClickCallback(EventHandler::onButtonClicked);
    TextBox textBox;
    textBox.setTextChangeCallback(EventHandler::onTextChanged);
    // ...
    return 0;
}

14.回调-异步回调:在异步编程中,可以使用静态回调函数来处理异步任务完成的通知

在这里插入图片描述

运行
在这里插入图片描述

代码

#include <iostream>
#include <functional>
#include <thread>

class AsyncTask {
public:
    typedef std::function<void(int result)> CompletionCallback;

    static int performActualTask(int input) {
        // 模拟耗时操作
        std::this_thread::sleep_for(std::chrono::seconds(2));
        return input * 2; // 模拟异步任务结果
    }

    static void performAsyncTask(int input, CompletionCallback callback) {
        std::thread([input, callback]() {
            int result = performActualTask(input);
            callback(result);
        }).detach();
    }
};

int main() {
    int input = 42;

    AsyncTask::performAsyncTask(input, [](int result) {
        std::cout << "Async task completed with result: " << result << std::endl;
    });

    // 主线程继续执行其他操作
    std::cout << "Main thread continues..." << std::endl;

    // 等待一段时间,以确保异步任务完成
    std::this_thread::sleep_for(std::chrono::seconds(3));

    return 0;
}

15.回调-插件化架构: 在插件化架构中,可以使用静态回调函数来扩展和定制主程序的功能

在这里插入图片描述

运行
在这里插入图片描述

代码

#include <iostream>
#include <functional>
#include <vector>

class Plugin {
public:
    typedef std::function<void()> ActionCallback;

    static void registerCustomAction(ActionCallback callback) {
        // 将回调函数注册为自定义动作
        customActions.push_back(callback);
    }

    static void executeCustomActions() {
        for (const ActionCallback& callback : customActions) {
            callback();
        }
    }

private:
    static std::vector<ActionCallback> customActions;
};

std::vector<Plugin::ActionCallback> Plugin::customActions;

int main() {
    Plugin::registerCustomAction([]() {
        std::cout << "Custom action 1 executed." << std::endl;
    });
    Plugin::registerCustomAction([]() {
        std::cout << "Custom action 2 executed." << std::endl;
    });
    Plugin::executeCustomActions();
    // ...
    return 0;
}

16.回调-回调集中管理: 使用静态回调函数集中管理程序中的不同事件和处理逻辑

在这里插入图片描述

运行
在这里插入图片描述

代码

#include <iostream>
#include <functional>
#include <map>

class CallbackManager {
public:
    typedef std::function<void()> Callback;

    static void registerCallback(const std::string& eventName, Callback callback) {
        eventCallbacks[eventName] = callback;
    }

    static void triggerEvent(const std::string& eventName) {
        auto it = eventCallbacks.find(eventName);
        if (it != eventCallbacks.end()) {
            (it->second)();
        }
    }

private:
    static std::map<std::string, Callback> eventCallbacks;
};

std::map<std::string, CallbackManager::Callback> CallbackManager::eventCallbacks;

int main() {
    CallbackManager::registerCallback("start", []() {
        std::cout << "Start event triggered." << std::endl;
    });
    CallbackManager::registerCallback("stop", []() {
        std::cout << "Stop event triggered." << std::endl;
    });
    CallbackManager::triggerEvent("start");
    CallbackManager::triggerEvent("stop");
    // ...
    return 0;
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/71217.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

悬崖传感器调试问题总结

悬崖传感器原理 使用ADC采样电路&#xff0c;周期的进行开/关灯&#xff0c;获取ADC采样值。根据预先设置好ADC门限&#xff0c;判断是否为悬崖。ADC的精度是12位&#xff0c;对应电路的电压是3.3伏&#xff0c;悬崖传感器通过开灯和关灯&#xff0c;接收的不同灯光强度&#x…

[数据集][目标检测]道路坑洼目标检测数据集VOC格式1510张2类别

数据集格式&#xff1a;Pascal VOC格式(不包含分割路径的txt文件和yolo格式的txt文件&#xff0c;仅仅包含jpg图片和对应的xml) 图片数量(jpg文件个数)&#xff1a;1510 标注数量(xml文件个数)&#xff1a;1510 标注类别数&#xff1a;2 标注类别名称:["keng","…

Redis缓存设计

缓存能够有效地加速应用的读写速度&#xff0c;同时也可以降低后端负载&#xff0c;对日常应用的开发至关重要。但是将缓存加入应用架构后也会带来一些问题&#xff0c;本文将针对这些问题介绍缓存使用技巧和设计方案。 1缓存的收益和成本 下图左侧为客户端直接调用存储层的架…

vector【1】介绍与使用(超详解哦)

vector 引言vector介绍接口使用默认成员函数迭代器容量元素访问数据修改 总结 引言 在string部分&#xff0c;我们详细的介绍了各个接口的使用&#xff0c;虽然其不属于STL的一部分&#xff0c;但是接口与STL中的容器相似&#xff0c;所以我们在学习使用vector等STL容器的使用…

JavaScript之BOM+window对象+定时器+location,navigator,history对象

一.BOM概述 BOM即浏览器对象模型,它提供了独立于内容而与窗口进行交互的对象 BOM的顶级对象是window 二.window对象的常见事件 1.窗口加载事件window.onload window.onload function(){} 或者 window.addEventListener("onload" , function(){}); window.onlo…

websocket知识点

http协议 http协议特点&#xff1a; 无状态协议每个请求是独立的单双工通信&#xff0c;且服务器无法主动给客户端发信息http协议受浏览器同源策略影响 http实现双向通信方法: 轮询长轮询iframe流sse EventSource websocket协议 websocket协议: 全双工协议支持跨域支持多…

近地面无人机植被定量遥感与生理参数反演技术

遥感&#xff08;RS-Remote Sensing&#xff09;——不接触物体本身&#xff0c;用传感器收集目标物的电磁波信息&#xff0c;经处理、分析后&#xff0c;识别目标物&#xff0c;揭示其几何、物理性质和相互关系及其变化规律的现代科学技术。 换言之&#xff0c;即是“遥远的感…

【Ubuntu】简化反向代理和个性化标签页体验

本文将介绍如何使用Docker部署Nginx Proxy Manager和OneNav&#xff0c;两个功能强大且易用的工具。Nginx Proxy Manager用于简化和管理Nginx反向代理服务器的配置&#xff0c;而OneNav则提供个性化的新标签页体验和导航功能。通过本文的指导&#xff0c;您将学习如何安装和配置…

SQL-每日一题【1517. 查找拥有有效邮箱的用户】

题目 表: Users 编写一个解决方案&#xff0c;以查找具有有效电子邮件的用户。 一个有效的电子邮件具有前缀名称和域&#xff0c;其中&#xff1a; 前缀 名称是一个字符串&#xff0c;可以包含字母&#xff08;大写或小写&#xff09;&#xff0c;数字&#xff0c;下划线 _ &…

[保研/考研机试] KY163 素数判定 哈尔滨工业大学复试上机题 C++实现

题目链接&#xff1a; 素数判定https://www.nowcoder.com/share/jump/437195121691718831561 描述 给定一个数n&#xff0c;要求判断其是否为素数&#xff08;0,1&#xff0c;负数都是非素数&#xff09;。 输入描述&#xff1a; 测试数据有多组&#xff0c;每组输入一个数…

Vue3入门

1. 为什么要学 Vue3 &#xff1f; Vue3 的优势&#xff1a; Vue2 选项式 API vs Vue3 组合式API 2. create-vue搭建Vue3项目 2.1 认识 create-vue create-vue是Vue官方新的脚手架工具&#xff0c;底层切换到了 vite&#xff08;下一代构建工具&#xff09;&#xff0c;为开发…

【Vue3】keep-alive 缓存组件

当在 Vue.js 中使用 <keep-alive> 组件时&#xff0c;它将会缓存动态组件&#xff0c;而不是每次渲染都销毁和重新创建它们。这对于需要在组件间快速切换并且保持组件状态的情况非常有用。 <keep-alive> 只能包含&#xff08;或者说只能渲染&#xff09;一个子组件…

SQL-每日一题【1484. 按日期分组销售产品】

题目 表 Activities&#xff1a; 编写解决方案找出每个日期、销售的不同产品的数量及其名称。 每个日期的销售产品名称应按词典序排列。 返回按 sell_date 排序的结果表。 结果表结果格式如下例所示。 示例 1: 解题思路 前置知识 group_concat函数的功能   将group by产生的…

Linux 基础篇(六)sudo和添加信任用户

一、sudo 1.是什么&#xff1f; 给被信任的普通用户授权&#xff0c;让被信任的普通用户能执行root用户才能执行的命令的一个命令。 2.为什么&#xff1f; 很多时候我们要在被信任的普通用户下执行一些root用户才能执行的命令&#xff0c;如 yum… 所以需要有一个命令能给普通用…

C字符串与C++ string 类:用法万字详解(上)

目录 引言 一、C语言字符串 1.1 创建 C 字符串 1.2 字符串长度 1.3 字符串拼接 1.4 比较字符串 1.5 复制字符串 二、C字符串string类 2.1 解释 2.2 string构造函数 2.2.1 string() 默认构造函数 2.2.2 string(const char* s) 从 C 风格字符串构造 2.2.3 string(co…

【计算机网络】——数据链路层

二、组帧 1、字符计数法 帧头部使用一个字符来表示帧的大小(包括第一个计数字符) &#xff08;此处一字符一个字节&#xff09; 2、字符填充收尾定界法 特定字符来定界帧的首和尾。若帧中数据段出现等同于特定字符的字符内容&#xff0c;前置一个转义字符。(类似于正则表达…

块、行内块水平垂直居中

1.定位实现水平垂直居中 <div class"outer"><div class"test inner1">定位实现水平垂直居中</div></div><style>.outer {width: 300px;height: 300px;border: 1px solid gray;margin: 100px auto 0;position: relative;}.te…

特征选择 | 变量重要性衡量

特征选择 | 变量重要性衡量 目录 特征选择 | 变量重要性衡量写在前面常规方法存在问题解决策略参考资料 写在前面 特征选择是预测模型构建的关键步骤&#xff0c;旨在1&#xff09;降低数据维度&#xff0c;减少计算量&#xff1b;2&#xff09;剔除一些无关或冗余变量&#xf…

科大讯飞分类算法挑战赛2023的一些经验总结

引言: ResNet是he kaiming大佬的早年神作&#xff0c;当年直接刷榜各大图像分类任务。ResNet是一种残差网络&#xff0c;咱们可以把它理解为一个子网络&#xff0c;这个子网络经过堆叠可以构成一个很深的网络&#xff0c;而ResNext在其基础上&#xff0c;进行了一定修改完善&am…

七、解析应用程序——枚举内容与功能

文章目录 1、web抓取2、发现隐藏内容2.1 蛮力技巧2.2 通过公布的内容进行推测2.3 利用公共信息 3、应用程序页面和功能路径4、发现隐藏参数 攻击应用程序的第一步是收集和分析与其有关的一些关键信息&#xff0c;以清楚了解攻击目标。解析过程首先是枚举应用程序的内容与功能&a…