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

news2024/11/24 11:39:36

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;
}

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

移远RM500U-CN模块直连嵌入式ubuntu实现拨号上网

目录 1 平台&#xff1a; 2 需要准备的资料 3 参考文档 4 编译环境与驱动移植 4.1 内核驱动添加厂家ID和产品ID 4. 2.添加零包处理 4.3 增加复位恢复机制 4.4 增加批量输出 批量输出 URB 的数量和容量 的数量和容量 4.5 内核配置与编译 5 QM500U-CN拨号&#xff08;在开…

tensorflow / tensorflow-gpu cuda cudNN tensorRT 安装,启用显卡加速

tensorflow / tensorflow-gpu cuda cudNN tensorRT 安装,启用显卡加速 说明 Tensorflow-GPU 已被移除。请安装 tensorflow 。 tensorflow 通过 Nvidia CUDA 支持 GPU 加速操作。 自 2019 年 9月发布 的 TensorFlow2.1 以来&#xff0c;tensorFlow 和 tensorflow-GPU 一直是同…

NFT Insider#102:The Sandbox重新上线LAND桥接服务,YGG加入Base生态

引言&#xff1a;NFT Insider由NFT收藏组织WHALE Members(https://twitter.com/WHALEMembers)、BeepCrypto&#xff08;https://twitter.com/beep_crypto&#xff09;联合出品&#xff0c;浓缩每周NFT新闻&#xff0c;为大家带来关于NFT最全面、最新鲜、最有价值的讯息。每期周…

【JVM】类装载的执行过程

文章目录 类装载的执行过程1.加载2.验证3.准备4.解析5.初始化6.使用7.卸载 类装载的执行过程 类装载总共分为7个过程&#xff0c;分别是 加载&#xff0c;验证&#xff0c;准备、解析、初始化、使用、卸载 1.加载 将类的字节码文件加载到内存(元空间&#xff09;中。这一步会…

实时时钟+闹钟

在江科大实时时钟的基础上添加闹钟的配置&#xff0c;参考http://t.csdn.cn/YDlYy。 实现功能 &#xff1a;每隔time秒蜂鸣器响一次、设置闹钟的年月日时分秒&#xff0c;到时间蜂鸣器响。 前三个函数没有变&#xff0c;添加 void RTC_AlarmInit(void) 闹钟的中断配置void…

分享Python技术下AutojsPro7云控代码

引言 有图有真相&#xff0c;那短视频就更是真相了。下面是三大语言的短视频。 Java源码版云控示例&#xff1a; Java源码版云控示例在线视频 Net源码版云控示例&#xff1a; Net源码版云控示例在线视频亚丁号-知识付费平台 支付后可见 扫码付费可见 Python源码版云控示例…

STM32CubeMX之freeRTOS消息通知(有点全能)

任务通知是任务自带的程序&#xff0c;不需要单独去创建 一&#xff1a; 二&#xff1a; 进入前不清除数据&#xff0c;退出清除数据参数 0x0000000000 0xffffffff的意思 三&#xff1a; 这里就是发送过去&#xff0c;然后把其存到了num中 不要有太多疑问&#xff0c;并不是发…

【Linux】TCP协议简介

TCP协议简介 TCP协议格式面向连接1.连接管理机制2.包序管理 可靠传输1.保证数据可靠到达对端2.保证数据的传输效率 面向字节流&#xff34;&#xff23;&#xff30;粘包问题 TCP协议格式 16位源端口号和16位目的端口号&#xff1a;标识数据从哪个进程来&#xff0c;到哪个进程…

阿里云Windows服务器安装部署MySQL数据库流程

阿里云百科分享如何在Windows系统ECS实例上手动部署MySQL数据库。 目录 前提条件 操作步骤 前提条件 使用本教程进行操作前&#xff0c;请确保您已经注册了阿里云账号。如还未注册&#xff0c;请先完成账号注册。操作系统&#xff1a;Windows Server 2012准备一台ECS云服务…

JDK、JRE、JVM:揭秘Java的关键三者关系

文章目录 JDK&#xff1a;Java开发工具包JRE&#xff1a;Java运行环境JVM&#xff1a;Java虚拟机关系概述 案例示例&#xff1a;Hello World结语 在Java世界中&#xff0c;你可能经常听到JDK、JRE和JVM这几个概念&#xff0c;它们分别代表了Java开发工具包、Java运行环境和Java…

计算机丢失msvcr71.dll解决办法,总结三个常见的解决方法

修复msvcr71.dll文件的过程中&#xff0c;我对系统动态链接库文件的重要性有了更深入的了解。这个文件对于许多使用Visual C编译的软件来说是必不可少的&#xff0c;缺失或损坏可能导致软件无法正常运行。因此&#xff0c;当遇到类似问题时&#xff0c;及时解决并修复这个文件是…

页面文件太小,无法完成操作。

1、右键“我的电脑”&#xff0c;选择“属性”&#xff1b; 2、点击“高级系统设置”&#xff1b; 3、点击“高级”&#xff0c;再点击“设置”&#xff1b; 4、选择“高级”&#xff0c;选择“程序”&#xff0c;点击“更改”&#xff1b; 5、 不要勾选“自动管理所有驱动器…

Spring Boot+Mybatis实现增删改查接口开发+测试(超详细建议收藏)

前言 Java也是测试必知必会的内容&#xff0c;特别是现在类似spring boot 等Java框架更是成为主流。之前实现的图书增删改查是用Python实现的&#xff0c;没看过的请移步&#xff1a;Flaskmysql 实现增删改查接口开发测试&#xff08;图文教程附源码&#xff09;&#xff0c;本…

教你如何使用AES对接口参数进行加密

教你如何使用AES对接口参数进行加密 前言 我们作为程序猿&#xff0c;在浏览网站的时候偶尔也会打开控制台看看请求的接口&#xff0c;我们会发现有些接口的传输是 “乱码” &#xff0c;那么这个乱码究竟是什么呢&#xff1f;为什么要这么做&#xff1f; 其实这个所谓的 “…

无涯教程-Perl - qq函数

描述 可以使用此函数代替双引号。这实际上不是一个函数,更像是一个运算符,但是如果您在其他程序员的程序中看到它却不记得它是什么,那么可能会在这里看。实际上,您可以使用任何一组定界符,而不仅仅是括号。 语法 以下是此函数的简单语法- qq ( string )返回值 该函数返回双…

De Bruijin序列与魔术(三)——De Bruijin序列的拓展思考

早点关注我&#xff0c;精彩不错过&#xff01; 在前面的文章中&#xff0c;我们已经介绍完经典DeBruijin序列的原理和魔术&#xff0c;相关内容请戳&#xff1a; De Bruijin序列与魔术&#xff08;二&#xff09;——魔术《De Bruijin序列》 De Bruijin序列与魔术&#xff08;…

Chord diagram | 啧啧啧!~人人必会的Chord diagram你不来学一学吗!?

1写在前面 啊啊啊啊啊&#xff01;&#xff01;&#xff01;&#xff01;~终于值完夜班休息了。&#x1f62d; 最近是大搞医疗反腐的日子&#xff0c;㊗️各位执法人员成绩满满&#xff01;~&#x1f912; 听说以后医务人员要年薪制了&#xff0c;完全搞不懂这些东西的初衷和理…

七夕好物分享,哪些礼物适合送男/女朋友?这几款好物最为合适!

七夕是个值得纪念的日子&#xff0c;牛郎织女鹊桥相会的故事百年流传&#xff0c;七夕是一个表达爱意的节日&#xff0c;送礼物是必不可少的&#xff0c;情侣们可以选择一份有意义的礼物&#xff0c;也可以选择对方需要的东西当做礼物来赠送&#xff0c;总的来说&#xff0c;送…

STM32F429IGT6使用CubeMX配置按键检测

1、硬件电路 2、设置RCC&#xff0c;选择高速外部时钟HSE,时钟设置为180MHz 3、配置GPIO引脚 4、生成工程配置 5、部分代码 /* USER CODE BEGIN 0 */ //按键检测函数 void KEY_Test(void) {if(SET HAL_GPIO_ReadPin(KEY1_GPIO_Port,KEY1_Pin)){while(SET HAL_GPIO_ReadPin(…

HCIP 链路聚合技术

1、链路聚合概述 为了保证网络的稳定性&#xff0c;仅仅是设备进行备份还不够&#xff0c;我们需要针对我们的链路进行备份&#xff0c;同时也增加了链路的利用率&#xff0c;提高带宽。避免一条链路出现故障&#xff0c;导致网络无法正常通信。这就可以使用链路聚合技术。 以…