【问题标题】:Default Constructor - deferring initialisation of member variables默认构造函数 - 推迟成员变量的初始化
【发布时间】:2015-07-03 02:37:24
【问题描述】:

我希望在 C++ 中为我的对象创建一个默认构造函数,当调用该构造函数时,它只是调用另一个构造函数,但具有固定值。

我一直在研究类似的问题: Are default constructors called automatically for member variables?Explicitly defaulted constructors and initialisation of member variables 这表明,当调用默认构造函数时,除非指定,否则成员变量的默认构造函数也会被调用。

但是,我遇到的问题是我正在使用的成员变量(来自 ARMmbed 库)没有默认构造函数 - 因此这不起作用。

有没有办法“延迟”这个问题,因为在默认构造函数调用的构造函数中,所有这些成员变量都被分配到并且一切正常 - 有没有办法让编译器知道这一点?

非常感谢!

我使用的头文件和实现代码如下!

class Motor: public PwmOut
{
public:
    //Constructor of 2 pins, and initial enable value
    Motor(); //Default constructor
    Motor(PinName dutyPin, PinName enable_pin, bool enable);  
private:
    bool enable; //Boolean value of enable
    DigitalOut enablePin; //Digital out of enable value
};

实施:

/**
* Default constructor
**/
Motor::Motor() //I don't want to initialise member variables here
{
    this = Motor::Motor(p23,p24,true); //As they are initialised in this constructor anyway?
}
/**
* Constructor for Motor class. Takes 1 PwmOut pin for PwmOut base class and 1 pin for DigitalOut enable
**/
Motor::Motor(PinName dutyPin, PinName enable_pin, bool enable):
    PwmOut(dutyPin), enablePin(enable_pin)
{
    //Logic in here - don't really want to duplicate to default constructor
}

【问题讨论】:

  • 可以delegate默认构造函数使用参数化构造函数。
  • 为什么不给第二个构造函数提供默认值,并将默认构造函数设为私有?
  • 我很感激我可以做到这一点,但是a)我真的不想在另一个构造函数中重复逻辑代码,b)我想知道理论上是否可以做到:)跨度>
  • @davidhood2 你的Motor 类继承自PwmOut 很奇怪。你不应该使用组合而不是继承吗?如果需要多个 PWM 输出引脚来驱动电机怎么办?
  • @Praetorian 它的物理设置方式(PwmOut 输出到电机芯片)让我认为电机对象是一种 PwmOut 而不是包含 PwmOut - 我只是按照is-a/has-a 约定

标签: c++ object constructor default-constructor


【解决方案1】:

您可以为此使用 C++11 的委托构造函数功能。

Motor::Motor()
: Motor(p23,p24,true)
{}

如果您的编译器不支持,那么您必须初始化 mem-initializer 列表中的数据成员,并将您不希望重复的逻辑移至另一个函数。

Motor::Motor()
: PwmOut(p23), enablePin(p24), enable(true)
{
    Init();
}

Motor::Motor(PinName dutyPin, PinName enable_pin, bool enable):
    PwmOut(dutyPin), enablePin(enable_pin), enable(enable)
{
    Init();
}

Motor::Init()
{
  // Move the initialization logic in here
}

正如Alf 在 cmets 中提到的那样,另一种选择是引入一个可以将构造委托给的基类。

class MotorBase
{
public:
    MotorBase(PinName enable_pin, bool enable)
    : enable(enable), enablePin(enable_pin)
    {
       // initialization logic goes in here
    }
private:
    bool enable; //Boolean value of enable
    DigitalOut enablePin; //Digital out of enable value
};

class Motor : public PwmOut, MotorBase
{
public:
    Motor(); //Default constructor
    Motor(PinName dutyPin, PinName enable_pin, bool enable);
};

Motor::Motor()
: PwmOut(p23), MotorBase(p24, true)
{}

Motor::Motor(PinName dutyPin, PinName enable_pin, bool enable):
    PwmOut(dutyPin), MotorBase(enable_pin, enable)
{}

【讨论】:

  • @davidhood2:在 C++03 中,您可以委托给人工基类。
  • @davidhood2 您可以添加一个Init()(可能是private)成员函数,或者按照阿尔夫的建议委托给某个基类
  • @praetorian:更新引入了一些关于引入冗余和使用 init 函数可憎以避免更多冗余的坏建议。哎哟。
  • @Cheersandhth.-Alf 是的,它远非理想,但除了重复的 mem-initializer 列表之外,它并不像通常的 init 函数两阶段初始化那么糟糕,因为你的课程不受欢迎在调用任一构造函数后仍将完全初始化。
猜你喜欢
  • 2015-06-21
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-08-09
  • 2016-04-05
  • 1970-01-01
  • 1970-01-01
  • 2015-10-07
相关资源
最近更新 更多