C++:将基于宏的属性系统转换为使用模板

标签 c++ design-patterns templates properties macros

我已经使用宏实现了满足以下要求的 C++ 属性系统:

  • 可以使用整数键引用属性
  • 可以通过通用的 Set/Get 访问属性
  • 属性(和属性键)必须是可继承的
  • 可以使用 getters/setters 注册属性

实现如下

  • 每个属性属于一个类
  • 每个属性都使用对其继承链唯一的键“声明”。 (使用相当聪明的 __ COUNTER __ hack 实现)。它具有以下特点
    • 根类(无父类)从 0 开始对其属性进行编号
    • 子类将从父类的最后一个 id + 1 开始对其属性进行编号

class A
{    
    static const unsigned int Property_0 = GET_KEY_MACRO; //expands to 0
    static const unsigned int Property_1 = GET_KEY_MACRO; //expands to 1     
};
class B : public A
{    
    static const unsigned int Property_0 = GET_KEY_MACRO(A); //expands to 2
    //and so forth    
};
class C : public A
{
     static const unsigned int Property_0 = GET_KEY_MACRO(A); //expands to 2. different inheritance chain
};

  • 其他代码可以使用静态常量 id 引用该属性。

objectinstance.SetValue(C::Property_0, 5)

  • 每个属性都是通过使用扩展为虚拟方法的宏来“注册”的。该宏目前允许注册属性类型、getter 和 setter

BEGIN_PROPERTIES
    REG_PROP(Property_0, int)
    REG_PROP_G(Property_1, int, getterFunc)
    ...
END_PROPERTIES

//expands to 

virtual void registerProperties()
{
    register(blah, blah, ...)
}

  • SetValue/GetValue 获取属性键并执行一些背景魔法来设置/获取它(已实现)

谁能想到与上述系统等效/更简单的基于模板的方法?

注意:此属性系统专为远程 RPCish 调用以及快速本地访问而设计。

最佳答案

这看起来像是一个经典的游戏属性系统,所以我建议您阅读这个 Gamasutra关于一个不需要太多代码的好系统的文章。也看看 boost.fusion看看它是否能帮到你。

以下是我的看法,可以忽略这个问题:

也就是说,我不太确定您使用模板会获得什么。仅仅是“宏不好”吗?

在使用了很多这样的系统之后,我得出的结论是,您通常通过添加属性系统来解决错误的问题。如果可以,请考虑使用像 C# 这样的语言,其中属性是一流的语言特性。

关于C++:将基于宏的属性系统转换为使用模板,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/1387535/

相关文章:

集合的 C++ vector 在执行 push_back 后给出段错误

c++ - boost lexical_cast 抛出异常

c++ - 在 std::string 中存储 unicode UTF-8 字符串

c# - 这是策略模式吗?

C++ typedef typename 类名::模板

c++ - 没有合适的构造函数和不兼容的声明错误

ruby-on-rails - 模型应该在 Rails 中命名吗?

design-patterns - 管理实体的历史对象

c++ - 如何为 C++ 模板编写测试?

c++ - 从模板基类继承构造函数而不重复模板参数?