Well, the issue with your second attempt is you'd need to do this:
sceneMusic::sceneMusic()
:staveMotion(ofVec2f(29, -staveImg.height()), \
ofVec2f(29, 249), 1, 0.1)
You specify the member names in the initializer lists. You specify a class name only when you are attempting to call a specific super-class constructor. Animation
is not a super-class of sceneMusic
.
The following "no matching function for call to Animation::Animation()" occurred for the same reason it would have occurred if you didn't have anything in your initializer list at all: the staveMotion
member was still trying to use Animation
s default constructor (just like the default constructor is used when you declare a variable Animation a;
), but Animation
does not have a default constructor.
Correcting the error in the initializer list takes care of both errors.
By the way, your second error regarding height()
: make sure there's actually a member function named height()
. You aren't showing the code but that error seems to indicate that you actually have a member variable named height
, not a function.
However, the above still won't fix your issue with having to call loadImage
first (thanks chris for reminding me about that in comments).
The easiest solution to that is to revert to your first attempt, and simply provide a default (no parameter) constructor for Animation
. As soon as you declare a non-default constructor, the compiler no longer generates a default constructor for you, and you have to explicitly declare/define Animation::Animation()
to provide it. That way, staveMotion
can be constructed with some default values (and won't have to be constructed in your initializer list) and then assigned to a proper value later.
A second option, by the way, that wouldn't require creation of temporary default Animation
s first (or perhaps more importantly, wouldn't require you to implement a default constructor that possibly breaks class invariants), would be to have staveImg
be a member field of sceneMusic
, give it a constructor that takes an image filename and loads the image, and declare it before staveMotion
in the member list. You wouldn't need an Animation
default constructor for this, and you could initialize everything in the initializer list:
sceneMusic :: sceneMusic () :
staveImg("./sceneMusic/stave_white.png"),
staveMotion(ofVec2f(29, -staveImg.height()), ofVec2f(29, 249), 1, 0.1)
{
}
A variation on that option is to construct the image ahead of time and pass it as a parameter to the sceneMusic
constructor. This wouldn't require a new constructor fo staveImg
.
A third option, which CantChooseUsernames brought up in the comments, is to make staveMotion
a pointer. You can initialize it to NULL
and construct a new Animation(...)
when necessary without requiring a default constructor. If you do this, don't forget to delete
it when you are done. An automatic pointer such as std::unique_ptr<Animation>
or one of the other smart pointers (boost
has some too) can make that easier on you.