1

I am looking to create a default constructor for my object in C++, which, when called, simply calls another constructor but with fixed values.

I have been looking at similar problems: Are default constructors called automatically for member variables? and Explicitly defaulted constructors and initialisation of member variables Which indicate, that when a default constructor is called, the default constructors of the member variables, unless specified, are also called.

However, the issue I have is that the member variables (from the ARMmbed library) I am using, do not have default constructors - hence this is not working.

Is there a way to "delay" this issue, because, in the constructor called by the default constructor, all these member variables are allocated to and it all works out - is there a way of letting the compiler know this?

Thanks very much!

The header and implementation code I am using is below!

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
};

Implementation:

/**
* 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
}
Community
  • 1
  • 1
davidhood2
  • 1,367
  • 17
  • 47
  • 2
    You can [delegate](http://stackoverflow.com/questions/13961037/delegate-constructor-c) the default constructor to use a parameterized constructor. – NathanOliver Apr 24 '15 at 13:10
  • why don't you just give default values to the second constructor and make default constructor private? – user3528438 Apr 24 '15 at 13:11
  • I appreciate I could have done that, but a) I dont really want to repeat the logic code in the other constructor and b) I want to know if theoretically, it can be done :) – davidhood2 Apr 24 '15 at 13:11
  • @davidhood2 It's odd that your `Motor` class inherits from `PwmOut`. Shouldn't you be using composition rather than inheritance? What if takes multiple PWM output pins to drive your motor? – Praetorian Apr 24 '15 at 13:43
  • @Praetorian The way its set up physically (the PwmOut ouput goes to a motor chip) led me to think that the motor object IS a type of PwmOut rather than containing a PwmOut - and I just followed the is-a/has-a convention – davidhood2 Apr 25 '15 at 11:26

1 Answers1

2

You can use C++11's delegating constructors feature for this.

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

If your compiler does not support that then you'll have to initialize the data members in the mem-initializer list, and move the logic that you do not want repeated to another function.

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
}

Another option, as Alf mentions in the comments, is to introduce a base class that you can delegate construction to.

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)
{}
Community
  • 1
  • 1
Praetorian
  • 106,671
  • 19
  • 240
  • 328
  • 1
    @davidhood2: In C++03 you can delegate to an artificial base class. – Cheers and hth. - Alf Apr 24 '15 at 13:12
  • 2
    @davidhood2 You can either add an `Init()` (maybe `private`) member function or delegate to some base class as Alf suggests – Praetorian Apr 24 '15 at 13:14
  • @praetorian: the update introduced some bad advice about introducing redundancy and using an `init` function abomination to avoid even more redundancy. ouch. – Cheers and hth. - Alf Apr 24 '15 at 13:15
  • @Cheersandhth.-Alf Yes, it's far from ideal but aside from the repeated mem-initializer list, it's not really as bad as the usual `init` function two phase initialization that's frowned upon because your class will still be fully initialized after a call to either constructor. – Praetorian Apr 24 '15 at 13:18