【发布时间】:2016-01-25 13:39:23
【问题描述】:
有哪些选项可用于在全局命名空间中创建具有大量参数的对象?我正在考虑临时对象/变量创建和可读性之间的权衡。
编辑
这是用于 Arduino 上的嵌入式编程。它将是控制一组嵌套对象的可重用库的主要对象。
背景: 我有一个测试 PCB,可以根据其最终用途进行不同的填充,我需要在一个易于使用的库中涵盖所有这些选项。我试图避免用户在使用对象之前意外丢失所需的初始化参数。
随意建设性地批评我的代码!
我能想到的两个选项是:
- 具有大量参数的构造函数。
- 具有单个结构参数的构造函数。
选项 1 看起来很混乱,而且参数很多,很难理解。
选项 2 需要一个临时结构变量以提高可读性。
下面的例子(通常我会分成标题等):
#include <Arduino.h>
class NestedClass {
public:
// Empty constructor for creation of unitialised object. Bad practice?
NestedClass() {
}
// Main constructor.
NestedClass(float voltageReference) :
voltageReference_(voltageReference) { // Use initialisation list.
}
float measureVoltage(uint_fast8_t channel) {
// Convert ADC value to absolute voltage.
return analogRead(channel) * (voltageReference_ / 1023);
}
private:
float voltageReference_;
};
class ComplexClass {
public:
enum class Mode
: uint_fast8_t {
MODE1,
MODE2,
MODE3
};
struct Parameters {
uint_fast8_t parameter1;
uint8_t parameter2;
float parameter3;
float parameter4;
Mode mode;
float voltageReference;
};
// Empty constructor for creation of unitialised object. Bad practice?
ComplexClass(void) {
}
// Big constructor. Messy when used.
ComplexClass(uint_fast8_t parameter1, uint8_t parameter2, float parameter3,
float parameter4, Mode mode, float voltageReference) {
// Could have used initialisation list instead.
this->parameter1_ = parameter1;
this->parameter2_ = parameter2;
this->parameter3_ = parameter3;
this->parameter4_ = parameter4;
this->mode_ = mode;
this->nestedClass_ = NestedClass(voltageReference); // Wasted temporary object with reassignment?
}
// Alternative constructor. Looks neater/more legible when used.
ComplexClass(Parameters parameters) {
this->parameter1_ = parameters.parameter1;
this->parameter2_ = parameters.parameter2;
this->parameter3_ = parameters.parameter3;
this->parameter4_ = parameters.parameter4;
this->mode_ = parameters.mode;
this->nestedClass_ = NestedClass(parameters.voltageReference); // Wasted temporary object with reassignment?
}
void megaMeasurements() {
// Do something involving nestedClass.measureVoltage().
}
private:
// Maybe put all of these in another struct for neatness?
uint_fast8_t parameter1_;
uint8_t parameter2_;
float parameter3_;
float parameter4_;
Mode mode_;
NestedClass nestedClass_;
};
//####################
// Start main code.
//####################
// Option 1:
// Not immediately obvious which value is for which parameter.
ComplexClass complexClass(1, 2, 3.30, 2.7, ComplexClass::Mode::MODE2, 5.00);
// Option 2:
// Unitialised object (sort-of).
ComplexClass complexClass2;
// Arduino standard function. Called once from main.cpp
void setup() {
// Option 2 continued:
ComplexClass::Parameters parameters;
parameters.mode = ComplexClass::Mode::MODE2;
parameters.parameter1 = 1;
parameters.parameter2 = 2;
parameters.parameter3 = 3.30;
parameters.parameter4 = 2.7;
parameters.voltageReference = 5.00;
complexClass2 = ComplexClass(parameters); // Reassignment. Wasteful?
}
// Arduino standard function. Called in a continuous loop after setup().
void loop() {
complexClass.megaMeasurements();
complexClass2.megaMeasurements();
}
【问题讨论】:
-
投票以基于意见的方式关闭(您没有定义“最佳”)。
-
与其传递许多单独的参数,不如将它们分组为逻辑结构,即其他对象,并传递其中的几个?也许你应该重新考虑你的设计,对象真的需要所有这些参数吗?其中一些不能有默认值吗?你当然可以重载构造函数,这样你就有一个使用一组参数的构造函数,以及另一个使用其他参数的构造函数。
-
@Cheers 和 hth。 - Alf 改写为“可用的选项”
-
将初始化代码放在返回完整对象的 lambda 中并就地调用 lambda。
-
我个人会使用结构或对象。或者更好,正如@JoachimPileborg 所说,一组不同的构造函数(一些参数很少,默认参数,一些参数更多)。我会避免向函数传递太多参数,因为编译器每次调用都需要保留一些内存
标签: c++ c++11 arduino embedded