全局数据的处理

在 C++ 中,全局数据,需要在多个地方使用,可以通过以下几种方式来表示和管理这些数据。

1. 全局变量

最直接的方式是使用全局变量。全局变量在程序的任何地方都可以访问,但需要谨慎使用,以避免潜在的线程安全问题和代码可维护性问题。

示例代码
cpp 复制代码
// 全局变量
std::array<double, 4> globalAxisPosition;

// 在任何地方访问和修改全局变量
void setGlobalAxisPosition(const std::array<double, 4>& position) {
    globalAxisPosition = position;
}

std::array<double, 4> getGlobalAxisPosition() {
    return globalAxisPosition;
}

2. 单例模式

单例模式是一种设计模式,确保一个类只有一个实例,并提供一个全局访问点。单例模式比全局变量更安全,因为它可以控制实例的创建和销毁。

示例代码
cpp 复制代码
#include <array>
#include <iostream>

class AxisData {
public:
    static AxisData& getInstance() {
        static AxisData instance; // 局部静态变量,确保只初始化一次
        return instance;
    }

    std::array<double, 4> getAxisPosition() const {
        return axisPosition;
    }

    void setAxisPosition(const std::array<double, 4>& position) {
        axisPosition = position;
    }

private:
    AxisData() {} // 私有构造函数,防止外部直接实例化
    AxisData(const AxisData&) = delete; // 禁止拷贝构造
    AxisData& operator=(const AxisData&) = delete; // 禁止赋值操作

    std::array<double, 4> axisPosition;
};

// 在任何地方访问和修改单例数据
void setGlobalAxisPosition(const std::array<double, 4>& position) {
    AxisData::getInstance().setAxisPosition(position);
}

std::array<double, 4> getGlobalAxisPosition() {
    return AxisData::getInstance().getAxisPosition();
}

3. 依赖注入

依赖注入是一种设计模式,通过将依赖项作为参数传递给类的构造函数或方法,而不是在类内部直接创建依赖项。这种方式可以提高代码的可测试性和可维护性。

示例代码
cpp 复制代码
#include <array>
#include <iostream>

class AxisData {
public:
    std::array<double, 4> getAxisPosition() const {
        return axisPosition;
    }

    void setAxisPosition(const std::array<double, 4>& position) {
        axisPosition = position;
    }

private:
    std::array<double, 4> axisPosition;
};

// 在任何地方访问和修改依赖注入的数据
class SomeClass {
public:
    SomeClass(AxisData& axisData) : axisData(axisData) {}

    void doSomething() {
        std::array<double, 4> position = {1.0, 2.0, 3.0, 4.0};
        axisData.setAxisPosition(position);
        std::array<double, 4> currentPosition = axisData.getAxisPosition();
        std::cout << "Current Position: " << currentPosition[0] << ", " << currentPosition[1] << ", " << currentPosition[2] << ", " << currentPosition[3] << std::endl;
    }

private:
    AxisData& axisData;
};

int main() {
    AxisData axisData;
    SomeClass someClass(axisData);
    someClass.doSomething();
    return 0;
}

4. 全局管理类

如果你有多个全局数据需要管理,可以创建一个全局管理类,将所有全局数据集中管理。

示例代码
cpp 复制代码
#include <array>
#include <iostream>

class GlobalDataManager {
public:
    static GlobalDataManager& getInstance() {
        static GlobalDataManager instance;
        return instance;
    }

    std::array<double, 4> getAxisPosition() const {
        return axisPosition;
    }

    void setAxisPosition(const std::array<double, 4>& position) {
        axisPosition = position;
    }

private:
    GlobalDataManager() {}
    GlobalDataManager(const GlobalDataManager&) = delete;
    GlobalDataManager& operator=(const GlobalDataManager&) = delete;

    std::array<double, 4> axisPosition;
};

// 在任何地方访问和修改全局数据
void setGlobalAxisPosition(const std::array<double, 4>& position) {
    GlobalDataManager::getInstance().setAxisPosition(position);
}

std::array<double, 4> getGlobalAxisPosition() {
    return GlobalDataManager::getInstance().getAxisPosition();
}

5. 线程局部存储(Thread Local Storage, TLS)

如果你的应用程序是多线程的,并且每个线程需要自己的全局数据副本,可以使用线程局部存储。

示例代码
cpp 复制代码
#include <array>
#include <iostream>
#include <thread>

thread_local std::array<double, 4> threadLocalAxisPosition;

void setThreadLocalAxisPosition(const std::array<double, 4>& position) {
    threadLocalAxisPosition = position;
}

std::array<double, 4> getThreadLocalAxisPosition() {
    return threadLocalAxisPosition;
}

void threadFunction() {
    std::array<double, 4> position = {1.0, 2.0, 3.0, 4.0};
    setThreadLocalAxisPosition(position);
    std::array<double, 4> currentPosition = getThreadLocalAxisPosition();
    std::cout << "Thread Position: " << currentPosition[0] << ", " << currentPosition[1] << ", " << currentPosition[2] << ", " << currentPosition[3] << std::endl;
}

int main() {
    std::thread t1(threadFunction);
    std::thread t2(threadFunction);
    t1.join();
    t2.join();
    return 0;
}

总结

  • 全局变量:简单直接,但可能导致线程安全问题和代码难以维护。
  • 单例模式:提供全局访问点,但控制实例的创建和销毁,更安全。
  • 依赖注入:提高代码的可测试性和可维护性,但需要在类之间传递依赖。
  • 全局管理类:集中管理多个全局数据,便于维护。
  • 线程局部存储:适用于多线程环境,每个线程有自己的数据副本。

根据你的具体需求选择合适的方法。如果数据是全局共享的且不需要线程安全,单例模式或全局管理类可能是较好的选择。如果数据是线程局部的,线程局部存储是更好的选择。

相关推荐
Scott9999HH1 小时前
【IIoT流量实战】蒸汽管道阀门全关却仍有流量?用 Python 实现涡街信号 FFT 频谱分析与温压全补偿积算网关,深度拆解靠谱的涡街流量计厂家硬核技术标准
开发语言·python
码智社2 小时前
AES加密原理详解及Java实现加解密实战
java·开发语言
AI云海3 小时前
python 列表、元组、集合和字典
开发语言·python
萧瑟余晖3 小时前
JDK 26 新特性详解
java·开发语言
马优晨4 小时前
Freemarker 完整讲解(后端 Java 模板引擎)
java·开发语言·freemarker·freemarker 完整讲解·freemarker模板引擎
人邮异步社区6 小时前
怎么把C语言学到精通?
c语言·开发语言
心平气和量大福大6 小时前
C#-WPF-控件-TextBox 数据绑定
开发语言·c#·wpf
ttwuai7 小时前
Cursor 生成 CRUD 后,Go 后台接口别只测 200:JWT、RBAC 和 tenant_id 怎么验
开发语言·后端·golang
এ慕ོ冬℘゜7 小时前
前端基础:什么是时间戳?JS获取时间戳三种方法与实战用途
开发语言·前端·javascript
执明wa7 小时前
LayoutInflater详解: XML是如何变成View的?
android·xml·开发语言·android studio