Error when trying to build a library

Hi,
I am building a library that is in a way an addition to the Matrix library. I named it MatrixController and what it does is that I can add extra methods for displaying rectangles, lines, circles, etc… on my LED matrix.

In this library I am creating a myMatrix from the Matrix class. But when I try to compile it, I get this error:

In file included from /Applications/Arduino 0011/hardware/cores/arduino/WProgram.h:6,
                 from MatrixControl.cpp:9:
/Applications/Arduino 0011/hardware/tools/avr/bin/../lib/gcc/avr/4.0.2/../../../../avr/include/avr/signal.h:36:2: warning: #warning "This header file is obsolete.  Use <avr/interrupt.h>."
In file included from MatrixControl.cpp:12:
MatrixControl.h:25:7: warning: no newline at end of file
MatrixControl.cpp:19:2: warning: no newline at end of file
MatrixControl.cpp: In constructor 'MatrixControl::MatrixControl(uint8_t, uint8_t, uint8_t, uint8_t)':
MatrixControl.cpp:14: error: no matching function for call to 'Matrix::Matrix()'
/Applications/Arduino 0011/hardware/libraries/Matrix/Matrix.h:46: note: candidates are: Matrix::Matrix(uint8_t, uint8_t, uint8_t, uint8_t)
/Applications/Arduino 0011/hardware/libraries/Matrix/Matrix.h:28: note:                 Matrix::Matrix(const Matrix&)

Here is my code for the header file:

#ifndef MatrixControl_h
#define MatrixControl_h

#include "WConstants.h"
#include "inttypes.h"

#include "Sprite.h"
#include "Matrix.h"

class Matrix;

class MatrixControl
{
  public:
    MatrixControl(uint8_t = 4, uint8_t = 3, uint8_t = 2, uint8_t = 1);

  private:
    uint8_t _pinData;
    uint8_t _pinClock;
    uint8_t _pinLoad;
    uint8_t _screens;
    Matrix _myMatrix;
};

#endif

and the source code of the .cpp:

extern "C" {
  // AVR LibC Includes
  #include <inttypes.h>
  #include <stdlib.h>

  // Wiring Core Includes
  #undef abs
}
#include "WProgram.h"
#include "WConstants.h"

#include "MatrixControl.h"

MatrixControl::MatrixControl(uint8_t data, uint8_t clock, uint8_t load, uint8_t screens /* = 1 */) {
  _pinData = data;
  _pinClock = clock;
  _pinLoad = load;
  _screens = screens;

  _myMatrix = Matrix(_pinData, _pinClock, _pinLoad, _screens);
}

Instead of:

MatrixControl::MatrixControl(uint8_t data, uint8_t clock, uint8_t load, uint8_t screens /* = 1 */) {
  _pinData = data;
  _pinClock = clock;
  _pinLoad = load;
  _screens = screens;

  _myMatrix = Matrix(_pinData, _pinClock, _pinLoad, _screens);
}

try this:

MatrixControl::MatrixControl(uint8_t data, uint8_t clock, uint8_t load, uint8_t screens /* = 1 */) :
  _myMatrix(_pinData, _pinClock, _pinLoad, _screens)
{
  _pinData = data;
  _pinClock = clock;
  _pinLoad = load;
  _screens = screens;
}

And stick that newline at the end of your source files. :)

Mikal

That indeed did the fix! thanks!

Now I would like to know why I actually need to do exactly that, so I can learn from it ;)

Basically, C++ has a special syntax for constructing a class that's a member of another one. To understand why, note that you can't create an instance of a class without calling one of its constructors. Since Matrix doesn't have a default (no argument) constructor, you need to pass it arguments. But you can't wait until you're inside the MatrixController constructor, because at that point the myMatrix would already exist (which is impossible without calling its constructor). So this syntax lets you initialize myMatrix ahead of time.

Quite correct. The syntax you were using before,

  _myMatrix = Matrix(_pinData, _pinClock, _pinLoad, _screens);

essentially directs the compiler to:
a) create _myMatrix using a no-argument constructor
b) create a temporary Matrix object using the 4-argument constructor
c) copy the temporary object to _myMatrix
d) destroy the temporary object

But since Matrix does not provide a “no-argument” (default) constructor, step (a) fails with the error you report.

The example I provided, which simply says:
a) directly create _myMatrix with the 4-argument constructor

is preferred, not only obviously because it works (in this case), but also because it is more efficient than the multi-stage construction would have been.

BTW, since MatrixControl is an extension of Matrix, you might consider making it inherit from that class to simplify the plumbing.

Mikal