0

我正在为使用 Sloeber(Eclipse 的 Arduino 插件)的 AVR 项目重构一些 C++ 代码。该项目有许多“设置”变量存储在 EEPROM 中,有上限和下限,需要字符串标签等。这些设置是不同的整数类型(uint8_t,int32_t等),我想要一个可以包含任何一个的包装器在这些类型中,一些方法继承自基类。我还希望能够形成所有设置变量的单个数组,以便我可以遍历它们。

一个简单的实现演示如下:

// Base class storing a uint8_t by default
class Base {
  public:
  typedef uint8_t numType;
  numType value = 0;  
};

// Child class changing 'numType' to a uint16_t
class Child: public Base {
  public:
  typedef uint16_t numType;
};

然后运行以下命令:

Base baseObj;
baseObj.value = 123;

Child childObj;
childObj.value = 12345;

我的意图是这childObj.value将是一个uint16_t,而baseObj.value将仍然是一个uint8_t

但是childObj.value计算结果为57,因此它仍被视为uint8_t。关于实现这种事情的方法有什么想法吗?

4

2 回答 2

0

除非子类有其他独特的行为,否则你只需要Base作为模板

template<typename T>
struct Base
{
    using numType = T;
    numType value = 0;
};

然后你可以为你想要的不同整数类型创建类型别名:

using Uint8 = Base<uint8_t>;
using Uint16 = Base<uint16_t>;
于 2019-02-01T12:23:11.503 回答
0

你想要的是一种类型擦除。您可以std::any直接使用(如果您只存储一个值,这将是有意义的)或构建自己的:

class Setting {
 public:
  Setting(std::string description) : _description(description) {}
  virtual ~Setting() = 0;

  std::string getDescription();

  template<typename T>
  T getValue();

 private:
  std::string _description;
};

template <typename T>
class SettingTyped : public Setting {
 public:
  SettingTyped(T value, std::string description)
      : Setting(description), _value(value) {}

  T getValue() { return _value; }

 private:
  T _value;
};

Setting::~Setting() = default;

template<typename T>
T Setting::getValue()
{
    auto* typedSetting = dynamic_cast<SettingTyped<T>*>(this);
    if (!typedSetting)
        throw std::runtime_error("Accessing with wrong type!");
    return typedSetting->getValue();
}

template<typename T>
auto makeSetting(T value, std::string description)
{
    return std::make_unique<SettingTyped<T>>(value, description);
}

bool foo() {
  std::vector<std::unique_ptr<Setting>> settings;
  settings.push_back(makeSetting<int>(3, "a setting"));

  return (settings[0]->getValue<int>() == 3);
}

演示

您可以使用它来弄清楚如何区分“原型设置”(默认值、边界)和“当前设置值”(实际存储的值)。例如,您仍然可以决定是否应在设置类型中对边界进行编码(并为每种设置创建单独的类型),或者边界是否(可能)是每个实例的不同常量。您的问题尚不清楚对此的要求。

当您遍历它们时,您希望如何知道每个设置的正确类型尤其不清楚。这里假设您以某种方式知道(例如基于描述?)。

于 2019-02-01T12:48:58.013 回答