Would some one please put me out of my misery. I've been working on this single issue for days and I don't know how to figure it out. I just want to create a single "debug" class that can be shared through out my project. Below is the simplified code to show the issue :
#include "Debug.h"
#include <Arduino.h>
Debug::Debug() : _state(false) {
if (_state == false){
Serial.begin(9600);
_state = true;
}
}
void Debug::line(const char *messageChar) {
if (_state){
const char *p;
p = messageChar;
while (*p) {
Serial.print(*p);
p++;
}
newline();
}
}
void Debug::line(int messageInt) {
if (_state){
Serial.print(messageInt);
newline();
}
}
void Debug::newline() {
if (_state){
Serial.println();
}
}
Errors
sketch\Puzzle.cpp: In member function 'void Puzzle::setup()':
Puzzle.cpp:6:21: error: no matching function for call to 'Box::Box(Debug*)'
_box = Box(&_debug);
^
In file included from sketch\Puzzle.h:5:0,
from sketch\Puzzle.cpp:1:
sketch\Box.h:10:5: note: candidate: Box::Box(Debug&)
Box(Debug &debug);
^~~
sketch\Box.h:10:5: note: no known conversion for argument 1 from 'Debug*' to 'Debug&'
sketch\Box.h:6:7: note: candidate: constexpr Box::Box(const Box&)
class Box {
^~~
sketch\Box.h:6:7: note: no known conversion for argument 1 from 'Debug*' to 'const Box&'
sketch\Box.h:6:7: note: candidate: constexpr Box::Box(Box&&)
sketch\Box.h:6:7: note: no known conversion for argument 1 from 'Debug*' to 'Box&&'
Main:3:8: error: use of deleted function 'Puzzle::Puzzle()'
Puzzle puzzle;
^~~~~~
In file included from D:\project\escape\puzzle box\source\Main\Main.ino:1:0:
sketch\Puzzle.h:7:7: note: 'Puzzle::Puzzle()' is implicitly deleted because the default definition would be ill-formed:
class Puzzle {
^~~~~~
Puzzle.h:7:7: error: no matching function for call to 'Box::Box()'
In file included from sketch\Puzzle.h:5:0,
from D:\project\escape\puzzle box\source\Main\Main.ino:1:
sketch\Box.h:10:5: note: candidate: Box::Box(Debug&)
Box(Debug &debug);
^~~
sketch\Box.h:10:5: note: candidate expects 1 argument, 0 provided
sketch\Box.h:6:7: note: candidate: constexpr Box::Box(const Box&)
class Box {
^~~
sketch\Box.h:6:7: note: candidate expects 1 argument, 0 provided
sketch\Box.h:6:7: note: candidate: constexpr Box::Box(Box&&)
sketch\Box.h:6:7: note: candidate expects 1 argument, 0 provided
sketch\Box.cpp: In constructor 'Box::Box(Debug&)':
Box.cpp:5:9: error: invalid initialization of non-const reference of type 'Debug&' from an rvalue of type 'Debug*'
_debug(&debug) {
^~~~~~
exit status 1
no matching function for call to 'Box::Box(Debug*)'
I've tried every combination of passing values, references and pointers along the entire path. Literally every variation.
I totally get that this is newbie stuff but I have watched hours and hours of youtube videos and read countless articles and can't find any information about how to do what I am attempting how to do. I really would appreciate help on how to get this to work.
When an object contains objects you have to provide any necessary arguments to those object's constructors in the parent constructor. Since you didn't define a constructor for Puzzle there was no way to provide Box with the required constructor argument.
Add this to Puzzle: public: Puzzle() : _box(_debug) {};
You tried to do it in Puzzle::setup() but by then it was too late. The Box object has to be constructed when the Puzzle is constructed.
@J-M-L : I tried all combinations of variables, pointers and references. When I did your suggestion the errors are :
sketch\Puzzle.cpp: In member function 'void Puzzle::setup()':
Puzzle.cpp:6:21: error: no matching function for call to 'Box::Box(Debug*)'
_box = Box(&_debug);
^
In file included from sketch\Puzzle.h:5:0,
from sketch\Puzzle.cpp:1:
sketch\Box.h:10:5: note: candidate: Box::Box(Debug&)
Box(Debug &debug);
^~~
sketch\Box.h:10:5: note: no known conversion for argument 1 from 'Debug*' to 'Debug&'
sketch\Box.h:6:7: note: candidate: constexpr Box::Box(const Box&)
class Box {
^~~
sketch\Box.h:6:7: note: no known conversion for argument 1 from 'Debug*' to 'const Box&'
sketch\Box.h:6:7: note: candidate: constexpr Box::Box(Box&&)
sketch\Box.h:6:7: note: no known conversion for argument 1 from 'Debug*' to 'Box&&'
sketch\Box.cpp: In constructor 'Box::Box(Debug&)':
Box.cpp:5:9: error: invalid initialization of non-const reference of type 'Debug&' from an rvalue of type 'Debug*'
_debug(&debug) {
^~~~~~
Main:3:8: error: use of deleted function 'Puzzle::Puzzle()'
Puzzle puzzle;
^~~~~~
In file included from D:\project\escape\puzzle box\source\Main\Main.ino:1:0:
sketch\Puzzle.h:7:7: note: 'Puzzle::Puzzle()' is implicitly deleted because the default definition would be ill-formed:
class Puzzle {
^~~~~~
Puzzle.h:7:7: error: no matching function for call to 'Box::Box()'
In file included from sketch\Puzzle.h:5:0,
from D:\project\escape\puzzle box\source\Main\Main.ino:1:
sketch\Box.h:10:5: note: candidate: Box::Box(Debug&)
Box(Debug &debug);
^~~
sketch\Box.h:10:5: note: candidate expects 1 argument, 0 provided
sketch\Box.h:6:7: note: candidate: constexpr Box::Box(const Box&)
class Box {
^~~
sketch\Box.h:6:7: note: candidate expects 1 argument, 0 provided
sketch\Box.h:6:7: note: candidate: constexpr Box::Box(Box&&)
sketch\Box.h:6:7: note: candidate expects 1 argument, 0 provided
exit status 1
no matching function for call to 'Box::Box(Debug*)'
@johnwasser : things are a little more complicated because I also need to initialize _debug as well as _box. I tried a few setups and could not make any progress. For example...
sketch\Puzzle.cpp: In member function 'void Puzzle::setup()':
Puzzle.cpp:5:3: error: only constructors take member initializers
_debug(Debug()),
^~~~~~
sketch\Box.cpp: In constructor 'Box::Box(Debug&)':
Box.cpp:5:9: error: invalid initialization of non-const reference of type 'Debug&' from an rvalue of type 'Debug*'
_debug(&debug) {
^~~~~~
Main:3:8: error: use of deleted function 'Puzzle::Puzzle()'
Puzzle puzzle;
^~~~~~
In file included from D:\project\escape\puzzle box\source\Main\Main.ino:1:0:
sketch\Puzzle.h:7:7: note: 'Puzzle::Puzzle()' is implicitly deleted because the default definition would be ill-formed:
class Puzzle {
^~~~~~
Puzzle.h:7:7: error: no matching function for call to 'Box::Box()'
In file included from sketch\Puzzle.h:5:0,
from D:\project\escape\puzzle box\source\Main\Main.ino:1:
sketch\Box.h:10:5: note: candidate: Box::Box(Debug&)
Box(Debug &debug);
^~~
sketch\Box.h:10:5: note: candidate expects 1 argument, 0 provided
sketch\Box.h:6:7: note: candidate: constexpr Box::Box(const Box&)
class Box {
^~~
sketch\Box.h:6:7: note: candidate expects 1 argument, 0 provided
sketch\Box.h:6:7: note: candidate: constexpr Box::Box(Box&&)
sketch\Box.h:6:7: note: candidate expects 1 argument, 0 provided
exit status 1
only constructors take member initializers
@PieterP : Thanks for your help. I made the changes you requested and it still resulted in errors (at bottom). I will also include all other relevant info (which is probably repeated in first post) to make sure we are in the same page :
Box.h
class Box {
private:
Debug &_debug;
public:
Box(Debug &debug);
};
sketch\Puzzle.cpp: In member function 'void Puzzle::setup()':
Puzzle.cpp:6:20: error: use of deleted function 'Box& Box::operator=(Box&&)'
_box = Box(_debug);
^
In file included from sketch\Puzzle.h:5:0,
from sketch\Puzzle.cpp:1:
sketch\Box.h:6:7: note: 'Box& Box::operator=(Box&&)' is implicitly deleted because the default definition would be ill-formed:
class Box {
^~~
Box.h:6:7: error: non-static reference member 'Debug& Box::_debug', can't use default assignment operator
Main:3:8: error: use of deleted function 'Puzzle::Puzzle()'
Puzzle puzzle;
^~~~~~
In file included from D:\project\escape\puzzle box\source\Main\Main.ino:1:0:
sketch\Puzzle.h:7:7: note: 'Puzzle::Puzzle()' is implicitly deleted because the default definition would be ill-formed:
class Puzzle {
^~~~~~
Puzzle.h:7:7: error: no matching function for call to 'Box::Box()'
In file included from sketch\Puzzle.h:5:0,
from D:\project\escape\puzzle box\source\Main\Main.ino:1:
sketch\Box.h:10:5: note: candidate: Box::Box(Debug&)
Box(Debug &debug);
^~~
sketch\Box.h:10:5: note: candidate expects 1 argument, 0 provided
sketch\Box.h:6:7: note: candidate: constexpr Box::Box(const Box&)
class Box {
^~~
sketch\Box.h:6:7: note: candidate expects 1 argument, 0 provided
sketch\Box.h:6:7: note: candidate: constexpr Box::Box(Box&&)
sketch\Box.h:6:7: note: candidate expects 1 argument, 0 provided
exit status 1
use of deleted function 'Box& Box::operator=(Box&&)'
I'm guessing this is because _debug and _box need to be defined. I tried to do this prior using the member initialization list and could not get it to work.
@PieterP : So that is exactly what I was trying to find. Is there a name where I learn more about that "approach" or whatever you want to call it. I have read like 30 articles about OOP with arduino and watched dozens of youtube videos and haven't seen.
I honestly can't tell you how much I appreciate your help.
You shouldn't do IO in constructors, constructors of global objects run before the main function and before the hardware is initialized.
It's common practice to do things like this in a begin() method.
You are saying that the Box instances will own their Debug instance (as an instance variable), so it's already instantiated for you. So you don't need to instantiate it again.
This should (untested) compile. You can get rid of some constructors main.ino:
My impression is that the intent was for the Puzzle and Box to share a single Debug. My code above tries to use the Debug copy constructor. I think the better way to do that is to have Box keep a pointer to the Debug and have the constructor initialize that pointer: Box.h