【问题标题】:Initialise complex object [closed]初始化复杂对象[关闭]
【发布时间】:2016-01-25 13:39:23
【问题描述】:

有哪些选项可用于在全局命名空间中创建具有大量参数的对象?我正在考虑临时对象/变量创建和可读性之间的权衡。

编辑

这是用于 Arduino 上的嵌入式编程。它将是控制一组嵌套对象的可重用库的主要对象。

背景: 我有一个测试 PCB,可以根据其最终用途进行不同的填充,我需要在一个易于使用的库中涵盖所有这些选项。我试图避免用户在使用对象之前意外丢失所需的初始化参数。

随意建设性地批评我的代码!

我能想到的两个选项是:

  1. 具有大量参数的构造函数。
  2. 具有单个结构参数的构造函数。

选项 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


【解决方案1】:

我的意见(基于我的实践):

  • 具有许多参数的构造函数看起来很乱,最好避免使用。此外,如果某些参数不好,则不能返回“false”,而抱怨的唯一方法就是抛出异常。如果你想这样做,最好定义一些带有几个参数的 init() 函数,如果参数不好,可以选择返回 false (或一些错误代码)来抱怨。在这种情况下,最好避免使用 #define 或 static const 声明的文字数值。

  • 另一种方法是直接(公共)或使用 set() 方法逐个分配值。在这种情况下,您可以将文字放入代码中。

【讨论】:

  • 关于坏值的好点。我正在尝试尽可能减少用户丢失所需参数的可能性。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-01-10
相关资源
最近更新 更多