当前位置: 首页 > news >正文

C++类型转换通用接口设计实现

目录

1.设计思路

2.通用转换接口实现

2.1.抽象基类(统一接口)

2.2.适配器子类(适配不同转换逻辑)

3.使用示例

4.统一接口调用(多转换器管理)

5.设计亮点

6.总结


1.设计思路

        在 C++ 中设计通用类型转换接口的核心目标是:屏蔽不同类型、不同转换逻辑的差异,提供统一的转换入口 ,同时支持灵活扩展(如适配成员函数、全局函数、lambda 等转换逻辑)。基于类型擦除(Type Erasure) 和适配器模式,支持任意类型间的转换。

1.抽象接口层:定义统一的转换接口,作为所有转换器的基类,屏蔽具体类型细节。

2.适配器层:通过模板子类适配不同形式的转换逻辑(如成员函数、全局函数、lambda 等),负责具体类型的转换。

3.类型擦除:通过模板参数去适配各种不同的参数。

4.类型安全:在适配器中通过严格的类型转换确保输入 / 输出类型匹配,避免未定义行为。

2.通用转换接口实现

2.1.抽象基类(统一接口)

定义 AbstractConverterFunction作为所有转换器的基类,定义统一的转换方法,接收 void* 类型的输入和输出(实现类型擦除),在子类里面去实现这个转换方法。通过统一接口,可在代码中用 AbstractConverterFunction* 指针调用任意类型的转换,无需关心具体转换逻辑的实现细节。

struct AbstractConverterFunction
{typedef bool (*Converter)(const AbstractConverterFunction *, const void *, void*);explicit AbstractConverterFunction(Converter c = nullptr): convert(c) {}AbstractConverterFunction(const AbstractConverterFunction&)=delete;AbstractConverterFunction& operator=(const AbstractConverterFunction&)=delete;Converter convert;
};

2.2.适配器子类(适配不同转换逻辑)

针对不同形式的转换逻辑(成员函数、带校验的成员函数、函数对象等),实现对应的模板适配器子类,继承 AbstractConverterFunction并实现 Convert 方法。

1.适配普通成员函数(From::toTo() const

当转换逻辑是 From 类的 const 成员函数,且无参数、返回 To 类型时使用。

template<typename From, typename To>
struct ConverterMemberFunction : public AbstractConverterFunction
{explicit ConverterMemberFunction(To(From::*function)() const): AbstractConverterFunction(convert),m_function(function) {}~ConverterMemberFunction();static bool convert(const AbstractConverterFunction *_this, const void *in, void *out){const From *f = static_cast<const From *>(in);To *t = static_cast<To *>(out);const ConverterMemberFunction *_typedThis =static_cast<const ConverterMemberFunction *>(_this);*t = (f->*_typedThis->m_function)();return true;}To(From::* const m_function)() const;
};
  • 核心作用:定义转换接口的 “外壳”,通过 Converter 函数指针存储具体的转换逻辑(由子类实现)。
  • 类型擦除:基类本身不依赖模板参数,通过 void* 接收输入 / 输出数据,隐藏了具体的 From/To 类型,使得非模板代码可以统一使用 AbstractConverterFunction* 调用转换。

2.适配带校验的成员函数(From::toTo(bool* ok) const

当转换可能失败(如字符串转数字),成员函数通过 bool* 输出成功标志时使用。

template<typename From, typename To>
struct ConverterMemberFunctionOk : public AbstractConverterFunction
{explicit ConverterMemberFunctionOk(To(From::*function)(bool *) const): AbstractConverterFunction(convert),m_function(function) {}~ConverterMemberFunctionOk();static bool convert(const AbstractConverterFunction *_this, const void *in, void *out){const From *f = static_cast<const From *>(in);To *t = static_cast<To *>(out);bool ok = false;const ConverterMemberFunctionOk *_typedThis =static_cast<const ConverterMemberFunctionOk *>(_this);*t = (f->*_typedThis->m_function)(&ok);if (!ok)*t = To();return ok;}To(From::* const m_function)(bool*) const;
};
  • 适用场景:当转换逻辑是 From 类的一个 const 成员函数,且该函数无参数、返回 To 类型时(如 class A { int toInt() const; };,将 A 转换为 int)。
  • 工作原理:通过模板参数 From/To 捕获具体类型,静态 convert 方法负责将 void* 安全转换为具体类型,再调用存储的成员函数完成转换。

3.适配函数对象(全局函数、lambda、std::function 等)

当转换逻辑是独立的可调用对象(输入 const From&,输出 To)时使用。

template<typename From, typename To, typename UnaryFunction>
struct ConverterFunctor : public AbstractConverterFunction
{explicit ConverterFunctor(UnaryFunction function): AbstractConverterFunction(convert),m_function(function) {}~ConverterFunctor();static bool convert(const AbstractConverterFunction *_this, const void *in, void *out){const From *f = static_cast<const From *>(in);To *t = static_cast<To *>(out);const ConverterFunctor *_typedThis =static_cast<const ConverterFunctor *>(_this);*t = _typedThis->m_function(*f);return true;}UnaryFunction m_function;
};
  • 适用场景:转换逻辑是独立的函数(非成员函数)、lambda 表达式或其他函数对象(如 std::function<To(From)>)。
  • 灵活性:支持任意可调用对象,例如 [](const std::string& s) { return s.size(); }(将 std::string 转换为 size_t)。

3.使用示例

假设我们有一个 String 类,需要转换为 int 或 size_t,可以通过这套体系实现:

#include <string>
#include <cassert>// 示例类:String
class String {
private:std::string m_str;
public:String(std::string s) : m_str(std::move(s)) {}// 成员函数:转换为长度(size_t)size_t length() const { return m_str.size(); }// 带校验的成员函数:转换为 int(类似 QString::toInt)int toInt(bool *ok) const {try {int val = std::stoi(m_str);*ok = true;return val;} catch (...) {*ok = false;return 0;}}
};int main() {// 1. 使用 ConverterMemberFunction:String → size_t(调用 length())ConverterMemberFunction<String, size_t> lenConverter(&String::length);String s1("hello");size_t len;// 调用转换:通过基类指针AbstractConverterFunction *converter = &lenConverter;bool ok = converter->convert(converter, &s1, &len);assert(ok && len == 5);  // 成功,长度为5// 2. 使用 ConverterMemberFunctionOk:String → int(调用 toInt)ConverterMemberFunctionOk<String, int> intConverter(&String::toInt);String s2("123");int num;ok = intConverter.convert(&intConverter, &s2, &num);assert(ok && num == 123);  // 转换成功String s3("abc");  // 无法转换为intok = intConverter.convert(&intConverter, &s3, &num);assert(!ok && num == 0);  // 转换失败,num为默认值0// 3. 使用 ConverterFunctor:String → std::string(调用 lambda)auto strToStdStr = [](const String& s) { return static_cast<std::string>(s);  // 假设String有转换运算符};ConverterFunctor<String, std::string, decltype(strToStdStr)> functorConverter(strToStdStr);std::string stdStr;ok = functorConverter.convert(&functorConverter, &s1, &stdStr);assert(ok && stdStr == "hello");  // 转换成功return 0;
}

4.统一接口调用(多转换器管理)

这套体系的核心价值是通过 AbstractConverterFunction* 统一管理不同类型的转换器,无需关心具体转换逻辑。例如在框架中存储多个转换器,动态调用:

#include <vector>int main() {// 创建多种转换器MyString s1("hello"), s2("123");std::string str("test");// 存储转换器指针(统一为 AbstractConverterFunction*)std::vector<AbstractConverterFunction*> converters;// 添加场景1的转换器(MyString → int,成员函数)converters.push_back(new ConverterMemberFunction<MyString, int>(&MyString::toInt));// 添加场景2的转换器(MyString → int,带校验)converters.push_back(new ConverterMemberFunctionOk<MyString, int>(&MyString::toInt));// 添加场景3的转换器(string → size_t,lambda)auto lambda = [](const std::string& s) { return s.size(); };converters.push_back(new ConverterFunctor<std::string, size_t, decltype(lambda)>(lambda));// 动态调用第一个转换器(MyString → int)int output1;converters[0]->convert(converters[0], &s1, &output1);std::cout << "转换器1结果:" << output1 << std::endl; // 5// 动态调用第二个转换器(带校验)int output2;converters[1]->convert(converters[1], &s2, &output2);std::cout << "转换器2结果:" << output2 << std::endl; // 123// 动态调用第三个转换器(string → size_t)size_t output3;converters[2]->convert(converters[2], &str, &output3);std::cout << "转换器3结果:" << output3 << std::endl; // 4// 释放内存for (auto c : converters) delete c;return 0;
}

5.设计亮点

1.类型擦除:通过基类 AbstractConverterFunction 屏蔽具体类型(From/To),使得非模板代码可以统一处理任意转换逻辑(只需存储 AbstractConverterFunction* 指针)。

2.多源适配:通过不同子类适配成员函数、带校验的成员函数、函数对象等多种转换源,覆盖大部分转换场景。

3.类型安全:虽然使用 void* 传递数据,但模板子类在 convert 方法中通过 static_cast 确保类型匹配(前提是使用时输入 / 输出类型与模板参数一致)。

4.轻量灵活:无需继承或虚函数重载,通过函数指针和模板封装转换逻辑,性能接近直接调用。

6.总结

这套代码是一个通用转换框架,核心通过 “抽象基类 + 模板子类 + 函数指针” 实现类型擦除,将不同形式的转换逻辑统一到同一接口下。适用于需要在运行时动态切换转换逻辑,或在非模板代码中处理多种类型转换的场景(如 Qt 的属性系统、数据绑定框架等)。使用时只需根据转换逻辑的类型(成员函数、带校验函数、lambda 等)选择对应的子类,即可通过基类指针统一调用。

http://www.dtcms.com/a/484303.html

相关文章:

  • 网站制作知名 乐云践新专家全网营销推广软件
  • C# 核心--事件型接口
  • 如保做网站赢利二手书交易网站策划书
  • 电商网站建设机构番禺网站建设多少钱
  • 网站建设seo优化方案网上买购物的软件有哪些
  • 网站里的地图定位怎么做交互设计名词解释
  • 河北网站制作报价手机百度问一问
  • 网站正在建设中 代码网络广告案例以及分析
  • 商务网站建设期末作业如何做资源论坛网站
  • 百度云盘网站开发恶意点击竞价时用的什么软件
  • 【YOLO模型】(4)--YOLO V3:目标检测的进化飞跃
  • 南京秦淮区建设局网站青岛百度推广优化怎么做的
  • 北京微信网站开发报价偷网站源码直接建站
  • 网站联盟平台江苏建设部网站
  • vue中构建脚手架
  • 房地产公司网站建设方案设计网站如何推广
  • xampp配置多网站推广平台收费标准
  • 网站的设计技术策划软件开发流程和规范
  • 做网站需要的导航数字营销 h5 网站开发
  • 网站icp备案新规wordpress上传七牛
  • 网站建设教程自学视频网站是用什么框架做的
  • 做企业网站进行推广要多少钱那些空号检测网站是怎么做的
  • 【cron】ubuntu 16 下cron不生效
  • 唐山网站推广做网站资源
  • 搜索网址网站建站品牌设计logo
  • 什么好的网站学做食品深圳企业网站建设公司
  • 做网站绿标廊坊网站建设电话
  • 库文件详解
  • 潍坊网站建设官网顺德移动端网站建设
  • 生成式人工智能赋能普通高中理科教学的创新路径研究