So I have a problem that I can't use the same variable name in multiple libraries even though it's private. I wonder why not? If it's private then it should only be used in it's own class anyway.
This is likely something I'm doing wrong but I can't figure out how to fix it.
//A.h
#ifndef A_h
#define A_h
#include <Arduino.h>
class A
{
public:
A();
private:
int variable;
};
#endif
//A.cpp
#include "A.h"
int variable = 0;
A::A() {
}
//B.h
#ifndef B_h
#define B_h
#include <Arduino.h>
class B
{
public:
B();
private:
int variable;
};
#endif
//B.cpp
#include "B.h"
int variable = 0;
B::B() {
}
EDIT: Forgot to include the error:
sketch\B.cpp.o (symbol from plugin): In function `B::B()':
(.text+0x0): multiple definition of `variable'
sketch\A.cpp.o (symbol from plugin):(.text+0x0): first defined here
collect2.exe: error: ld returned 1 exit status
exit status 1
Compilation error: exit status 1
The variables you are declaring global in A.cpp and B.cpp have nothing to do with the private variables inside class A and class B. To initialize the private variable:
private:
int variable = 0;
or
A::A() {
variable = 0;
}
or
A::A() : variable(0) {
// This one is needed if 'variable' is declared 'const'. If so,
// it has to be initialized before the rest of the constructor runs.
}
If you make the variable 'static' (shared by all instances of class A) you define and initialize it with:
Many thanks for the good explanation ! It seems I haven't fully learnt the basics about classes in C++ yet.
Now I understand a bit better what I'm doing.
I can't make them static so I just removed the declarations in the .cpp files and now it compiles nicely. Initializing them was what caused the problem in the first place I guess.
I have read many times that you should try not to initialize inside the header file. Is there a reason for this other that it makes them messy? Initializing in the constructor seems like a good way to do it.
It's perfectly fine to initialize a class member variable in the header file. In fact, I don't know where else you would do it. Post a reference for these "many times".
The error message you reported was due, not to class members, but to a conflict where two global variables had the same name, in this case variable.
//A.cpp
#include "A.h"
int variable = 0; // global
A::A() {
}
You could have solved that (or at least got rid of the error message) by adding the keyword static. This is a special use of static when applied to global variables and has the function of hiding them from other translation units (code resident in other files). This is not the same as static applied to class member variables.
Anyway, even if you had done this, it would not have achieved your objective of initialising class member variables, as has already been pointed out.
Yeah I had somehow got the false assumption that variables had to be "initialized" twice. Like "listing the functions" from .cpp in the header file. Don't remember the correct word now for "listing the functions" in the header file.
Splitting a class into two files is a bit confusing for me coming from C#.