god对象的总体配置对象和后期初始化
Overall configuration object for a god object and late initialisation
这个问题有两个主要部分:将配置值存储在单个文件/位置和延迟所包含对象的初始化。
存储配置值
我有一个嵌入式程序,用于控制半自动测试的PCB测试夹具。我想把所有的极限/测试参数存储在一个地方(最好是只读/常量),这样以后就可以很容易地定位和调整它们。问题是,有些值在嵌套结构中,我所知道的初始化这些对象的唯一方法是使用可怕的初始化器列表,在该列表中,所有可追溯性都丢失了(或者使用了一个几乎同样糟糕的构造函数)。
例如
class Configuration {
public:
struct NestedStruct {
float value1;
float value2;
float value3;
};
struct ContainerStruct {
int value1;
float value2;
NestedStruct nested1;
NestedStruct nested2;
NestedStruct nested3;
float value3;
};
// Initialise struct data member.
// Not obvious which value is which?
constexpr static const ContainerStruct containerStruct {5, 2.3, 1.4, 4.2, 0.7, 3.5, 2.5, 3.5, 0.2, 0.2, 0.1, 4.6};
// Slightly more readable
constexpr static const ContainerStruct containerStruct {5, 2.3, {1.4, 4.2, 0.7}, {3.5, 2.5, 3.5}, {0.2, 0.2, 0.1}, 4.6};
};
如何在保持可读性的同时,将由复杂/嵌套结构值组成的只读配置值存储在一个位置?
控制器/上帝对象初始化
我决定将核心功能封装到一个单独的控制器对象中,该对象实例化多个包含的对象。其中一个对象通过指针传递给其他一些对象。我使用上面提到的配置值(有很多!)来初始化这些对象。
使用initializer列表会使Controller类的构造函数又长又乱。我可以绕过这一点的一种方法是为包含的对象创建一个空的构造函数,并使用一个单独的initializer函数,我可以在Controller的构造函数的主体中调用该函数。
然而,我一直读到两步/延迟初始化是不好的,因为对象不能立即使用。还有别的办法吗?
也许还有比把它包在神的物体里更好的方法吗?
我想存储在一个地方的示例参数:
Adc对象参数:
float voltageReference;
uint8_t slaveSelectPin;
NavigationButtons对象参数:
struct AdcValues {
uint_fast16_t buttonUp;
uint_fast16_t buttonDown;
uint_fast16_t buttonLeft;
uint_fast16_t buttonRight;
uint_fast16_t buttonCentre;
uint_fast8_t tolerance;
};
UutPower对象参数:
struct CurrentCompensation {
float LowX;
float LowC;
float MidX;
float MidC;
float HighX;
float HighC;
};
电压测试对象参数:
struct TestParameter {
float scalingFactor; // Potential divider scaling for voltages >voltageRef.
float limitLower;
float limitUpper;
const char *signalName;
};
// Lots of nested structs.
struct TestParameters {
TestParameter tb1_1;
TestParameter tp15;
TestParameter tp4;
TestParameter tp1;
TestParameter tp3;
TestParameter tp20;
TestParameter tp12;
TestParameter tp29;
TestParameter tp28;
TestParameter con3_6;
TestParameter con3_2;
}
其他参数:
float currentLimitLow;
float currentLimitHigh;
const char *version;
感谢您的帮助。
最可行的选择可能是将结构拆分为单独的const
变量,您必须通过变量命名或其他方式对它们进行分组。
一旦有了这个,就可以更改链接器文件,为每个变量提供一个专用地址。或者,编译器可能有一个非标准的扩展,比如@
运算符。
这允许您单独初始化每个这样的变量。
这对于维护来说非常好,因为添加或删除变量不会更改其他不相关变量的地址。仔细规划你的记忆地图,在这里和那里留下"洞",以便将来扩展。如果适用的话,考虑对齐(如果你使用一些8位垃圾MCU,这不会是一个问题)。
这样做的另一个优点是,可以将const
变量本地化到使用它们的文件中,而不是将它们保留在全局"怪物结构"中。
- 用C++中的CPerson(类)类型的对象初始化STL矢量
- 对象初始化中是否允许指向此成员的指针?
- 对象初始化后在C++中显示 char 数组时的异常行为
- 为什么两种不同的对象初始化方式给出不同的输出
- (2 问题)"类"类型重新定义(即使 #pragma 一次),以及静态函数内的静态成员对象初始化?
- afxmem.cpp中的对象初始化差异
- 删除通过取消引用新对象初始化的对象
- 如何使用sregex_token_iterator对象初始化向量
- 关于默认构造函数,对象初始化/使用C++ OOP
- C++ 基元类型初始化与对象初始化
- 哪个函数负责C++全局范围内的类对象初始化?
- C++中构造函数的对象初始化出现问题
- 如何修复模板 BST 类的对象初始化
- 无法在 QML/C++ 中使用绑定对象初始化 UI
- 为什么参数可以在对象初始化时通过赋值运算符传递给构造函数?
- 类对象初始化的二维向量
- GCC:当层次结构中存在虚拟继承时,C++11 内联对象初始化(使用 "this")不起作用
- 对象初始化
- 类对象初始化
- 使用从另一个类继承的类的对象初始化成员对象