C++11 环境下的类型安全泛型容器:TpVariant 使用指南

TpVariant 简介

TpVariant 是一个类型安全的联合体(union)封装类。它可以存储多种不同类型的值,并在运行时动态切换类型,这是 C++11 标准库不提供的功能

与 C++11 的对比

C++11 的局限性:

  • C++11 只有 union,但不支持类型安全和自动内存管理
  • 没有 std::variant(这是 C++17 才引入的特性)
  • 需要手动管理类型标识和内存释放

TpVariant 的优势:

  • 类型安全的泛型容器
  • 自动内存管理
  • 支持自定义类型
  • 在 C++11 环境下即可使用

支持的数据类型

TpVariant 支持丰富的内置类型:

基础类型

  • 布尔型: bool
  • 整数型: int8_t, uint8_t, int16_t, uint16_t, int32_t, uint32_t, int64_t, uint64_t
  • 浮点型: float, double
  • 字符串: const char*, std::string, TpString

几何类型

  • 矩形: TpRect
  • 尺寸: TpSize
  • : TpPoint

容器类型

  • 向量: TpVector<T>
  • 集合: std::set<T>

自定义类型

  • 任意类型: 通过模板构造函数支持任意自定义类型

核心使用方法

1. 创建和赋值

基础类型
// 整数类型
TpVariant intVar = 42;
TpVariant int64Var = (int64_t)1234567890;

// 浮点类型
TpVariant floatVar = 3.14f;
TpVariant doubleVar = 2.718;

// 布尔类型
TpVariant boolVar = true;

// 字符串类型
TpVariant strVar = "Hello TinyPiX";
TpVariant tpStrVar = TpString("World");
几何类型
// 矩形
TpVariant rectVar = TpRect(0, 0, 100, 200);

// 尺寸
TpVariant sizeVar = TpSize(640, 480);

// 点
TpVariant pointVar = TpPoint(50, 100);
容器类型
// 向量
TpVector<int32_t> intVec = {1, 2, 3, 4, 5};
TpVariant vecVar = intVec;

// 集合
std::set<std::string> strSet = {"apple", "banana", "orange"};
TpVariant setVar = strSet;

2. 自定义类型支持

支持存储任意自定义类型

// 自定义结构体
struct UserInfo {
    std::string name;
    int age;
    UserInfo(const std::string& n, int a) : name(n), age(a) {}
};

// 存储自定义类型
UserInfo user("张三", 25);
TpVariant customVar = user;

// 获取自定义类型
UserInfo retrievedUser = customVar.toCustom<UserInfo>();

自定义类型的赋值操作:

// 重新赋值自定义类型
UserInfo newUser("李四", 30);
customVar = newUser;  // 自动管理内存

3. 类型检查

TpVariant var = 42;

// 检查是否为空
if (var.isNull()) {
    // 空值处理
}

// 检查具体类型
if (var.isInt32()) {
    int32_t value = var;  // 隐式转换
}

if (var.isString()) {
    std::string str = var.toString();
}

// 检查自定义类型
if (var.isCustom<UserInfo>()) {
    UserInfo user = var.toCustom<UserInfo>();
}

4. 类型转换

隐式转换

TpVariant 提供了丰富的隐式转换操作符:

TpVariant intVar = 42;
int32_t value = intVar;  // 自动转换

TpVariant floatVar = 3.14f;
float fValue = floatVar;

TpVariant boolVar = true;
bool bValue = boolVar;
显式转换
TpVariant var = "123";
std::string str = var.toString();

TpVariant rectVar = TpRect(0, 0, 100, 200);
TpRect rect = (TpRect)rectVar;

5. 容器操作

向量转换
// 创建整数向量
TpVector<int32_t> intVec = {1, 2, 3, 4, 5};
TpVariant vecVar = intVec;

// 转换回向量
TpVector<int32_t> retrievedVec = vecVar.ToInt32Array();
集合操作
// 创建字符串集合
std::set<std::string> strSet = {"apple", "banana", "orange"};
TpVariant setVar = strSet;

// 获取集合引用(可修改)
std::set<std::string>& refSet = setVar.ToStringSet();
refSet.insert("grape");

6. 比较操作

TpVariant var1 = 42;
TpVariant var2 = 42;
TpVariant var3 = 100;

// 相等比较
if (var1 == var2) {
    // 值相等
}

// 不等比较
if (var1 != var3) {
    // 值不等
}

7. 赋值操作

TpVariant var;

// 赋值不同类型
var = 42;           // 整数
var = 3.14;         // 浮点数
var = "Hello";      // 字符串
var = TpRect(0, 0, 100, 200);  // 矩形

// 拷贝赋值
TpVariant var2 = var;

8. 获取类型信息

TpVariant var = 42;

// 获取类型枚举值
uint16_t typeId = var.getVariantType();

// 获取类型名称
const char* typeName = var.variantTypeName();
// 返回 "int32"

9. 清空操作

TpVariant var = "Hello";

// 清空变量
var.clear();

// 检查是否为空
if (var.isNull()) {
    // 已清空
}

TpVariant 独有功能总结

相比 C++11 标准库,TpVariant 提供了以下独特功能:

  1. 类型安全的泛型容器: 在 C++ 11 环境下实现类似 C++17 std::variant 的功能
  2. 自动内存管理: 无需手动管理类型标识和内存释放
  3. 自定义类型支持: 通过模板构造函数支持任意自定义类型
  4. 丰富的内置类型: 支持基础类型、几何类型、容器类型
  5. 隐式类型转换: 提供便捷的类型转换操作符
  6. 容器集成: 与 TpVectorstd::set 无缝集成

内存管理机制

TpVariant 提供了完善的内存管理 :

  1. 自动拷贝: 拷贝构造和赋值时自动深拷贝数据
  2. 自动释放: 析构时自动释放内存
  3. 类型切换: 赋值不同类型时自动清理旧数据

最佳实践建议

1. 类型检查

在使用前始终进行类型检查,避免类型不匹配:

TpVariant var = getValue();
if (var.isInt32()) {
    int32_t value = var;
    // 安全使用
}

2. 避免频繁类型切换

频繁改变 TpVariant 的类型会导致内存分配/释放开销:

// 不推荐
TpVariant var;
for (int i = 0; i < 1000; i++) {
    var = i;           // 整数
    var = "text";      // 字符串
}

// 推荐
TpVariant intVar;
TpVariant strVar;
for (int i = 0; i < 1000; i++) {
    intVar = i;
    strVar = "text";
}

3. 自定义类型的生命周期

确保自定义类型支持拷贝构造:

struct MyData {
    std::string name;
    MyData(const MyData& other) : name(other.name) {}  // 拷贝构造
};

TpVariant var = MyData();  // 安全

TinyPiXOS开发者联盟

源码级支持 + 真实项目:TinyPiXOS开发者联盟招募中​。
获取开发资料
技术手册
项目官网
B 站视频

感谢支持和关注,请点赞、收藏和转发!

Logo

Agent 垂直技术社区,欢迎活跃、内容共建。

更多推荐