calling a function in constructor

This is a discussion on calling a function in constructor within the C++ Programming forums, part of the General Programming Boards category; A constructor i have written includes a function call to 'InitButtons()' to initialise the positions of a series of buttons ...

  1. #1
    Registered User rogster001's Avatar
    Join Date
    Aug 2006
    Location
    Liverpool UK
    Posts
    1,438

    calling a function in constructor

    A constructor i have written includes a function call to 'InitButtons()' to initialise the positions of a series of buttons and collision boxes, i have stepped through the constructor i see everything work properly,
    however when i am in a later do_logic() member function that needs these values to work, i see that in the watch window the buttons are all at crazy non-values again, as if they are local and uninitialised
    the collision boxes retain their values ok though, any ideas what could be going wrong here? Is it wrong to include a function call from a constructor or something? half of it works though...

    the data members in question are all private, the class itself inherits from a virtual base class, only the Do-logic() function mentioned here is a member of the base class though.

    i will post class def, constructor and other function if suggested

  2. #2
    Registered User
    Join Date
    Jun 2005
    Posts
    6,344
    Constructors can call functions.

    If InitButtons() is an overridden virtual function, some behaviours may not be what you expect. For example;
    Code:
    #include <iostream>
    class A
    {
         public:
    
          A() {InitButtons();}
          virtual void InitButtons() {std::cout << "A\n"};
    };
    
    class B : public A
    {
       public:
          B() : A() {};
          void InitButtons() { std::cout << "B\n"};   // override inherited function
    };
    
    int main()
    {
          B b;
    }
    will always print out the string "A", because the call InitButtons() in A's constructor always resolves to A::InitButtons(), not to B::InitButtons(). My guess is that you are experiencing something like this - expecting an over-ridden version of a function to be called, but a base class version is instead.

    If my guess is wrong (you haven't really provided enough information) you're going to need to provide a small but complete sample of code that illustrates your problem.
    Right 98% of the time, and don't care about the other 3%.

  3. #3
    Guest Sebastiani's Avatar
    Join Date
    Aug 2001
    Location
    Waterloo, Texas
    Posts
    5,708
    I'm guessing you're trying to call a virtual function within the constructor? If so, you will have to call the derived function explicitly - just keep in mind that doing so can be problematic (the 'complete' object isn't yet fully constructed at that point, after all).

    If not, then just post the relevant code.

  4. #4
    Registered User rogster001's Avatar
    Join Date
    Aug 2006
    Location
    Liverpool UK
    Posts
    1,438

    code example

    i thought maybe the problem is that the data is used by virtual and non virtual functions,and that when in one or the other the data members are created newly in that scope, no idea, i dont know, like i say its crazy because one array of elements remains ok,
    its probably best with some code then >>

    here is the class definition, defined in MenuState.h

    Code:
    class MenuState : public StateEngine
    {
        private:
    
        SDL_Surface* Buttonsource;
        SDL_Rect menubutton[6];          //this is the array of structs that automagically change
        SDL_Rect menuclip[6];
        SDL_Rect playarea[2];            //collison boxes to check for change of state, these values stay ok after initialisation
    
        int count;
        int lastbutton;
        int testX, testY;
    
        public:
    
        void HandleEvents();              //these 3 are the only shared functions in the virtual base class
        void Do_Logic();
        void Render();
        void InitButtons();               //this is not in the base class ...perhaps it should be private??
    
        MenuState();
        ~MenuState();
    };
    here is the constructor in the MenuState.cpp file

    Code:
    MenuState::MenuState()
    {
        temp = NULL;                     //this is global
        Buttonsource = NULL;
    
        temp = SDL_LoadBMP("buttonsheet.bmp");
        Buttonsource = SDL_DisplayFormat(temp);
        SDL_FreeSurface(temp);
    
        count = 0;
        lastbutton = 10;
        testX = 0;
        testY = 0;
    
        InitButtons();
    }
    and here is the definition of InitButtons(); from the same file

    Code:
    void MenuState::InitButtons()
    {
        int Ypos = 200;
    
        for(count = 0; count < 6; count++) 
        {
            menubutton[count].x = 673; menubutton[count].y = Ypos;    //attributes of normal size buttons
            menubutton[count].w = 196; menubutton[count].h = 83;
    
            Ypos += 100;
    
            if(count == 3)                   //sort out width height and position of the two smaller save and load buttons
            {
                menubutton[count].x = 690;
                menubutton[count].y = 511;
            }
            if(count == 4)
            {
                menubutton[count].x = 775;
                menubutton[count].y = 511;
                Ypos -= 100;                 // pull value back or it will miss the next button (bc ypos will= 700 and 600 is max)
            }
            if(count == 3 || count == 4)
            {
                menubutton[count].w = 75;
                menubutton[count].h = 60;
            }
        }
    
        for(count = 0; count < 2; count++)  //Set the size of the collision boxes...(these values remain ok after initialising)
        {
             if(count == 0)
            {
                playarea[count].x = 210; playarea[count].y = 120; 
                playarea[count].w = 210; playarea[count].h = 290; 
            }
            if(count == 1)
            {
                playarea[count].x = 110; playarea[count].y = 235; 
                playarea[count].w = 420; playarea[count].h = 175; 
            }
        }
    }
    Last edited by rogster001; 12-29-2009 at 09:06 AM.

  5. #5
    Guest Sebastiani's Avatar
    Join Date
    Aug 2001
    Location
    Waterloo, Texas
    Posts
    5,708
    Looks kosher, as far as I can tell. What values are changing, by the way? Are you sure they aren't being changed after the constructor call (it might be a good idea to print out the contents of each after the constructor completes, to be sure)? May need to see some more code, though.

  6. #6
    Registered User rogster001's Avatar
    Join Date
    Aug 2006
    Location
    Liverpool UK
    Posts
    1,438

    found it

    its the contents of the array 'menubuttons'
    in the init function i can see them initialise correctly as watches
    but then in my do_logic or handleevents function. (ie afterwards) all the width and height shows as 0, and the x and y show as eg 44134
    i know its failing and is not just the watch view as the values fail conditions they should meet if initialised correctly

    EDIT >>

    I just found the problem, for some reason the render() function is nuking the values in the array, as soon as it has blitted each button i see the values change to nonsense, how on earth does that happen?

    heres the code, this is the very next thing stepped into after construction >

    Code:
    void MenuState::Render()
    {
    
        for(count = 0; count < 6; count++)
        {
            SDL_BlitSurface(Buttonsource, &menuclip[count], screen, &menubutton[count]);
        }
    
    }
    or maybe the problem is the other way around and the values i see appearing in the watches in render() are the ones that have actually been carried into the function, god knows
    Last edited by rogster001; 12-29-2009 at 09:37 AM. Reason: show problem

  7. #7
    Registered User rogster001's Avatar
    Join Date
    Aug 2006
    Location
    Liverpool UK
    Posts
    1,438
    i have now realised that the menuclip array was never setup, i sorted that and thought it might be solved but no;
    but what it has shown is that in this blit function the contents of the fourth argument are being written over by the contents of the second argument each time it is called.

    haha....erm...which seems to be how it works...i just never saw it like that in action before...the problem is solved. thanks all
    Last edited by rogster001; 12-29-2009 at 10:44 AM.

  8. #8
    Guest Sebastiani's Avatar
    Join Date
    Aug 2001
    Location
    Waterloo, Texas
    Posts
    5,708
    Ah, the old "source is the destination" problem! Yes, that's a very common mistake, and can indeed be quite tricky to track down. Well, glad to hear that you got everything sorted out, then. Cheers.

  9. #9
    Super Moderator VirtualAce's Avatar
    Join Date
    Aug 2001
    Posts
    9,596
    Just out of curiousity what are you going to do if InitButtons() fails?

  10. #10
    Registered User
    Join Date
    Sep 2004
    Location
    California
    Posts
    3,246
    Quote Originally Posted by Bubba View Post
    Just out of curiousity what are you going to do if InitButtons() fails?
    All he is doing is integer assignment. What can fail?
    bit∙hub [bit-huhb] n. A source and destination for information.

  11. #11
    Algorithm Dissector iMalc's Avatar
    Join Date
    Dec 2005
    Location
    New Zealand
    Posts
    6,307
    There's way too many magic numbers in that code for my liking!
    My homepage
    Advice: Take only as directed - If symptoms persist, please see your debugger

    Linus Torvalds: "But it clearly is the only right way. The fact that everybody else does it some other way only means that they are wrong"

  12. #12
    Guest Sebastiani's Avatar
    Join Date
    Aug 2001
    Location
    Waterloo, Texas
    Posts
    5,708
    Quote Originally Posted by iMalc View Post
    There's way too many magic numbers in that code for my liking!
    No doubt. The really scary thing is that many IT departments still crank out that sort of rubbish! Oh well, more job security for us, I suppose.

  13. #13
    Super Moderator VirtualAce's Avatar
    Join Date
    Aug 2001
    Posts
    9,596
    All he is doing is integer assignment. What can fail?
    More appropriately then what is he going to do if any of those SDL functions in the constructor fail? A hard-coded menu such as this one does not seem all that useful. The class could be abstracted to encapsulate a type of menu or any menu and be much more useful and eliminate the need for InitButtons().

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Compiling sample DarkGDK Program
    By Phyxashun in forum Game Programming
    Replies: 6
    Last Post: 01-27-2009, 02:07 AM
  2. Undefined Reference Compiling Error
    By AlakaAlaki in forum C++ Programming
    Replies: 1
    Last Post: 06-27-2008, 11:45 AM
  3. Replies: 28
    Last Post: 07-16-2006, 11:35 PM
  4. Calling a Thread with a Function Pointer.
    By ScrollMaster in forum Windows Programming
    Replies: 6
    Last Post: 06-10-2006, 08:56 AM
  5. Contest Results - May 27, 2002
    By ygfperson in forum A Brief History of Cprogramming.com
    Replies: 18
    Last Post: 06-18-2002, 01:27 PM

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21