Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why does my Arduino Class Constructor require an argument?

Tags:

c++

arduino

avr

I am writing a very simple Arduino class to control two motors.

I have a simple class definition inside my header file Motor.h:

class Motor 
{
  public:
    Motor();
    void left(int speed);
    void right(int speed);
    void setupRight(int rightSpeed_pin, int rightDirection_pin);
    void setupLeft(int leftSpeed_pin, int leftDirection_pin);
  private:
    int _rightMotorSpeedPin;
    int _rightMotorDirectionPin;
    int _leftMotorSpeedPin;
    int _leftMotorDirectionPin;
};

In my main library file, Motor.cpp, I have the following Class constructor:

Motor::Motor() {
  // Intentionally do nothing.
}

When I try to initialize my class in my primary program with the line:

Motor motor();

I get the following compilation error:

MotorClassExample.ino: In function 'void setup()':
MotorClassExample:7: error: request for member 'setupRight' in 'motor', which is of non-class type 'Motor()'
MotorClassExample:8: error: request for member 'setupLeft' in 'motor', which is of non-class type 'Motor()'
request for member 'setupRight' in 'motor', which is of non-class type 'Motor()'

The baffling part is that if I include even a garbage, throwaway argument to the Motor Class constructor like this:

class Motor
{
   public:
      Motor(int garbage);
      ...

And in the .cpp file:

Motor::Motor(int garbage) { }

And in my main file:

Motor motor(1);

Everything works perfectly without complaint. I've done quite a bit of searching through Arduino forums, but found nothing to explain this odd behavior. Why would the class constructor require an argument? Is this some weird relic tied in to AVR or something?

like image 498
Eric Ryan Harrison Avatar asked Dec 09 '15 03:12

Eric Ryan Harrison


2 Answers

You've run into the "most vexing parse" problem (named that because it's annoying, of course).

Motor motor(); declares a function called motor that takes no arguments and returns a Motor. (No different from int test(); or similar)

To define an instance of Motor called motor, use Motor motor; with no parentheses.

like image 166
user253751 Avatar answered Nov 15 '22 06:11

user253751


As an addition to the accepted answer:

Since C++11 you can use the "uniform initialization" syntax. An advantage of uniform initialization over functional form is, that braces cannot be confused with function declarations, which happened in your case. The syntax can be used like the functional one, except that you use braces {}.

There are some good examples over here

Rectangle rectb;   // default constructor called
Rectangle rectc(); // function declaration (default constructor NOT called)
Rectangle rectd{}; // default constructor called 
like image 30
Rev Avatar answered Nov 15 '22 07:11

Rev