基对象和继承对象,用于将标准变量包装在C++中
Base and inherited objects to wrap stdint variables in C++
我正在为使用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
。关于实现这种事情的方法有什么想法吗?
你想要
的是一种类型擦除形式。您可以直接使用 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);
}
演示
你可以用它来弄清楚如何区分"原型设置"(默认值,边界)和"当前设置值"(实际存储的值)。例如,您仍然可以决定是否应在设置类型中对边界进行编码(并为每种设置创建单独的类型),或者边界是否是每个实例(可能)不同的常量。从您的问题中不清楚对此的要求。
尤其不清楚在循环访问每个设置时如何知道每个设置的正确类型。这里假设您以某种方式知道(例如,基于描述?
除非子类具有其他唯一行为,否则您只需要Base
作为模板:
template<typename T>
struct Base
{
using numType = T;
numType value = 0;
};
然后,您可以为所需的不同整数类型创建此类型别名:
using Uint8 = Base<uint8_t>;
using Uint16 = Base<uint16_t>;
相关文章:
- 包装一个对象并假装它是一个 int
- 错误:"释放后使用包装器对象 (WRAPPER_ESCAPE)"
- C++包装库:在堆栈上分配C++ C 中的对象
- 将对象传递给函数而不将其包装到 std::ref 中,而参数被指定为 const 引用
- 在 C++ 对象包装器中安全地包含 C 代码
- 如何将 c++ 类包装到 python 中,以便我可以使用 pybind11 访问其成员的公共方法(成员是一个对象指针)
- 在 C++ 中为 C 样式对象创建一个透明包装类
- 如何将包装类的对象用作包装函数中的参数
- 如何包装对象,使它们成为无法交互的单独类型?
- 由 pybind11 包装的对象的内存开销
- 将抽象值对象保存在包装器中和继承的用法中
- 将numpy对象传递到Pythonqt包装器
- 如何将 Python 中的字节对象传递给用 Swig 包装的C++函数
- 将 C 对象的数组包装到类C++
- 泛型对象包装器
- OpenGL对象包装器中的自动绑定
- 如何编写安全的原子对象包装器?
- 我的GLSL着色器对象/包装器是否应该封装加载/设置VertexArrayObject
- 将C++对象包装在外部“C”中
- 移动值/对象包装器的构造函数