Calling a constructor from a constructor doesn't seem to work

Hey Everyone, here’s what I have

Sparkoomba::Sparkoomba()
{
    Sparkoomba(57600,0, false);
}
Sparkoomba::Sparkoomba(unsigned int _baud, unsigned char _ddPin, bool automaticMode)
{
    this->_baud = _baud;
    this->_ddPin = _ddPin;
    this->_automaticMode = automaticMode;
    this->_oiState = STATE_SLEEP;
    this->lastCommand = 255;
    this->lastCommandSuccess = false;
    
    this->_LEDBits = 0;                 // All Off
    this->_powerLEDColor = 125;         // Orange
    this->_powerLEDIntensity = 255;     // Full Intensity
}

When I setup the object like this: robot = Sparkoomba(57600,0,true) the values for baud, ddPin, and automaticMode are correctly saved in the object. If I, however, do robot = Sparkoomba() all the values return 0.

Any ideas? Am I not allowed to call a constructor from inside of another constructor

Hi @harrisonhjones

You can’t do this unless you are using C++ 11 constructor chaining. See this:

http://www.parashift.com/c++-faq-lite/init-methods.html

What you want is initialization lists anyway:

http://www.parashift.com/c++-faq-lite/init-lists.html

So one constructor with default values in an init list is the way to go here.

2 Likes

Awesome. I’ll look into that today!

You could have your no-arg constructor like this:

Sparkoomba::Sparkoomba(unsigned int _baud=57600, unsigned char _ddPin=0, bool automaticMode=false) {
  // ...
}

(This should go in the header file if you have a class declaration separate from the implementation.)

1 Like

Thanks @mdma!

What exactly does

This should go in the header file if you have a class declaration separate from the implementation

mean?

Hi @mdma

You might want to read the second link in my post above about init lists.

Your way is great but lots of folks recommend init lists instead. It really depends on how expensive it is o construct the RHS of the assignment so with simple types like this it is fine.

Guys, before this gets too academic, I think @harrisonhjones needs to see an example of what either scenario looks like! As for “cost”, how many classes are we talking about. One, maybe two!!! You guys are just too smart sometimes :stuck_out_tongue:

1 Like

Ah yeah, totally init lists over assignment is a good rule. I wasn’t considering the c’tor implementation, just focusing on getting a no-arg constructor.

Although here I personally find the direct assignment more readable, especially since we can assign like this->x = x. And as you say, it’s doubtful there’s any penalty for initializing primitives. (And if there were a penalty, it’s not critical unless it’s some inner loop.)

@harrisonhjones - using init lists would give you a c’tor like this:


Sparkoomba::Sparkoomba(unsigned int baud=57600, unsigned char ddPin=0, bool automaticMode=false)
 : _baud(baud), _ddPin(ddPin), _automaticMode(automaticMode), _oiState(STATE_SLEEP), lastCommand(0), ...etc..
{
}

1 Like

What I mean there is sometimes if you need to use a class in several pieces of code, you put it in a header file:

// foo.h

class Foo {
public:
    Foo(int howMany=2);  // no function body here
};

And then put the function bodies in a separate .cpp file

// foo.cpp

Foo::Foo(int howMany) {
   for (int i=0; i<howMany; i++) {
     Serial.println("Foo");
   }
}

But since you asked, I’m guessing you’re not doing that!

2 Likes

Oh… I’m fairly sure I’m doing that. I hadn’t considered any other way! :P. I guess I could have just put the class in the top of my main .cpp file? Doesn’t sound too re-usable…

1 Like

@harrisonhjones, so you would put the Class prototype in the .h file and the Class definition (including init lists) in the .cpp for the library. Then you include the library’s .h file in your app, giving you re-usability. Not sure what you mean by “Doesn’t sound too re-usable”? :smile:

Sorry for the confusion. I meant doing it like this:

Library.h with defitions
Library.cpp with actual code

is a lot more re-usable then the alternate method:

EverythingInMyMain.cpp

which I hadn’t even considered as an option

3 Likes

Yep! You got it! Reusability is the key…aaaaand then there’s also laziness…in my worst afflicted moments, I’ve just put the entire class def in a header! :stuck_out_tongue:

Although that might come from the fact I’m used to scripting and Java where you don’t have to faff about separate header and body.

Although truthfully, with C++0x/C++11 the “laziness” has really taken off and we now have many header-only libraries (e.g. boost, STL etc.)