2

So I've managed to narrow my problem down to these 6 lines of code:

sf::Sprite charSpr;
charSpr.setTexture(charTex);

int _characterSets[] = {1, 8, 8};
AnimatedObject characterObj(&charSpr, 51, 75, 3, _characterSets);
PlayerObject character(&characterObj);

Somehow, through the course of these lines it always comes to pass that the default constructor is called for the AnimatedObject class even though I'm clearly only calling the constructor for AnimatedObject that takes an sf::sprite, two ints and an int array.

PlayerObject Constructor

PlayerObject::PlayerObject(AnimatedObject* _animObj){
    anim = *_animObj;

    dynamic = false;
    for(int i = 0; i < 2; i++){
        position[i] = 0;
        velocity[i] = 0;
        acceleration[i] = 0;
        gravity[i] = 0;
    }
}

AnimatedObject Constructor

AnimatedObject::AnimatedObject(sf::Sprite* _s, int _w, int _h, int _st, int _fs[]){
    sprite = *_s;

    width = _w;
    height = _h;

    sets = _st;
    set = 1;

    frames.insert(frames.end(), &_fs[0], &_fs[sets]);
    frame = 1;
}

Error Message with AnimatedObject default constructor made private

In file included from PlayerObject.cpp:3:0:
AnimatedObject.hpp: In constructor ‘PlayerObject::PlayerObject()’:
AnimatedObject.hpp:9:3: error: ‘AnimatedObject::AnimatedObject()’ is private
   AnimatedObject();
   ^
PlayerObject.cpp:6:28: error: within this context
 PlayerObject::PlayerObject(){
                            ^
In file included from PlayerObject.cpp:3:0:
AnimatedObject.hpp: In constructor ‘PlayerObject::PlayerObject(AnimatedObject*)’:
AnimatedObject.hpp:9:3: error: ‘AnimatedObject::AnimatedObject()’ is private
   AnimatedObject();
   ^
PlayerObject.cpp:13:52: error: within this context
 PlayerObject::PlayerObject(AnimatedObject* _animObj){
theStandard
  • 212
  • 2
  • 9
  • 1
    You have not provided all the relevant code. – Werner Erasmus Jul 18 '14 at 05:32
  • 8
    Simple solution: make default constructor private and see where compiler complains. Problem doesn't seem to be in the code shown. – hyde Jul 18 '14 at 05:32
  • I'm afraid you're going to have to clarify. Do you mean that you'd like to see my class definition(s)? The last line of my code here is the line at which the error occurs (or at least at which the default constructor is called) and my code doesn't function after this line. – theStandard Jul 18 '14 at 05:38
  • 1
    the constructor for `PlayerObject` does something it shouldn't – sp2danny Jul 18 '14 at 05:39
  • 3
    Maybe `PlayerObject`s has an `AnimatedObject` member that's not initialized in the constructor's member initializer list. That would end up calling the default constructor. – Pradhan Jul 18 '14 at 05:40
  • 1
    @Pradhan that seems likely due to the line `anim = *_animObj;` – M.M Jul 18 '14 at 05:44

2 Answers2

3

You need to initialize anim. Currently, you are assigning it a value after it has been default constructed. You need to use the constructor initialization list to explicitly initialize data members, otherwise they get default initialized:

PlayerObject::PlayerObject(AnimatedObject* _animObj) : anim(*_animObj)
{
  ....
}

The problem here is that you need to figure out how to cope with the situation where _animObj is NULL. If it cannot be NULL, better pass a reference:

PlayerObject::PlayerObject(const AnimatedObject& _animObj) : anim(_animObj)
{
  ....
}

Otherwise, you have to figure out the desired semantics and implement them.

Also note that names starting with an _ are reserved in some contexts, so it is better not to use them.

juanchopanza
  • 223,364
  • 34
  • 402
  • 480
  • Thanks for the answer (I'm not ignoring hyde's answer though). Never would have figured this out on my own. Can you link to some kind of documentation on constructor initialization lists? – theStandard Jul 18 '14 at 05:51
  • 1
    @theStandard There is something here: http://en.cppreference.com/w/cpp/language/initializer_list, otherwise this should be covered in any good introductory book. See [this list of books](http://stackoverflow.com/questions/388242/the-definitive-c-book-guide-and-list). – juanchopanza Jul 18 '14 at 05:54
2

You must initialize anim in initializer list. Otherwise it gets default constructed first. So, like this:

PlayerObject::PlayerObject(AnimatedObject* _animObj) :
    anim(*_animObj)
{
    //snip
}

You should do this for all member variables which are objects, to avoid them being first default-constructed, then assigned to. For some things like primitive types and pointers it does not really matter which you do, but I think most C++ coders would prefer all member variables be initialized in the initializer list, except those where you do want the default constructor to be called, and except where not practical (like those arrays of yours).

hyde
  • 60,639
  • 21
  • 115
  • 176