You're missing a default constructor. Try modifying your class like this:
class Light {
int pin;
public:
Light()=default; //<-- put this in
Light(int p) {
pin = p;
}
};
As to why you're not automatically generating a default constructor, it's because you're already declaring a constructor of some type, so the compiler won't generate a default one (from http://en.cppreference.com/w/cpp/language/default_constructor, see sections on implicitly declared/defined constructors).
In response to the comment:
Wouldn't it attempt to call the default constructor instead of the one
which passes the arguments?
When your executing code gets to the last line:
Button my_button(my_led);
You're instantiating a Button and a Light as part of the Button instantiation process. Without specifying a default Light::Light() constructor, you're leaving out instructions on how to instantiate a Light object without a value, which you need to do before copying the value of my_led into my_button. You'll get the results you intended, you're just currently leaving out instructions to the compiler on how to perform an intermediate step, i.e. instantiate Light without any arguments.
Some things to think about:
What are you really trying to do? Just by looking at your instruction code:
Light my_led(0);
Button my_button(my_led);
It seems to me like you're trying to say "a light named my_led exists" and "a button named my_button exists and needs my_led". Do you want the button to refer to a specific LED that exists already, or just an LED that has the same values?
If you think you'll want to refer to the actual LED from that button then you might want to consider doing the following:
class Button {
const Light *ledLight;
public:
Button(const Light& l) :
ledLight{&l}
{}
};
That way, your Button has a pointer to the Light you created, and whatever you do with the Light inside your Button code will be performed on the Light object you already instantiated, instead of some separate copy of Light you create by copy-constructing Light with your current Button constructor.
If you want the button to actually modify the light, revise Button like so:
class Button {
// constant reference to changeable object
Light * const ledLight;
public:
/**
* You're providing a reference to a light that can be changed
* (i.e. button code can toggle lit status or something)
*/
Button(Light & l) :
ledLight{&l}
{}
};
The above you could think of as having an unchanging wire from the button to the LED. If you think you'll be reassigning the LED that gets lit from the button, you'd take out the const keyword from the pointer member in Button as well.
my_button.ledLightwill not change the contents ofmy_led. You copied the object.my_leddirectly tomy_button? So that changes from the button affect its contents.ledlighta referenceLight& ledLight;and then:Button(Light& l) { }in the constructor declaration?