Jump to content
  • Advertisement
Sign in to follow this  
LatchGameDev

SDL and Copy Constructors

This topic is 2146 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

So I've been wrestling with this problem for a few days now. So I have a entity class and I thought I would use a vector to make it so i could have a dynamic array of the entity's. It crashed horribly and i learned that in my SmartImage class (located inside the entity class) was only making a shallow copy. So i'm trying to make a deep copy using the copy constructor. My program compiles but it crashes as soon as it launches. It seems even initializing the SmartImage class will cause it to crash. What am i doing wrong?

 

SmartImage.h

class SmartImage
{
    private:
            bool image_loaded;
    public:
           SmartImage();
           ~SmartImage();
           // copy constructor:
           SmartImage (const SmartImage& param);
           
           SDL_Surface *surface;
           void load(std::string filename);
           void copy_surface(SDL_Surface *target_surface);
};
#include"SmartImage.cpp"

SmartImage.cpp

SmartImage::SmartImage()
{
 surface=NULL;
 image_loaded = false;     
}

SmartImage::~SmartImage()
{
 SDL_FreeSurface(surface);      
}

// copy constructor
SmartImage::SmartImage (const SmartImage& param)
{         
 surface = SDL_DisplayFormat(param.surface);          
}

void SmartImage::load(std::string filename)
{
    if(image_loaded == false)
    {
     surface = load_image(filename);
     image_loaded = true;
    }    
    else
    {
     SDL_FreeSurface(surface);
     surface = load_image(filename);
    }  
}

void SmartImage::copy_surface(SDL_Surface *temp_surface)
{
     if(image_loaded == true)
     {
      SDL_FreeSurface(surface);               
     }
 surface = SDL_DisplayFormat(temp_surface); 
 image_loaded = true;     
}
Edited by LatchGameDev

Share this post


Link to post
Share on other sites
Advertisement

Do you know about the rule of three? It looks like you didn't define an operator=, so you probably don't. Read about it and you may have an easier time understanding your problem.

Share this post


Link to post
Share on other sites

I know of the rule of three but i'm having trouble implementing it. I'm looking at a tutorial and trying to implement the copy constructor,copy assignment operator, and the destructor. This is what i'm looking at http://www.cplusplus.com/doc/tutorial/classes2/ and i'm about half way down the page.

 

Modified the .h to try and include the assignment operator. It more matches what the tutorial has but I don't think it's going to do what i want. I don't exactly understand how to use the assignment operator tho. Still crashes when I try to make a SmartImage object which means something is majorly wrong right?

class SmartImage
{
    private:
            bool image_loaded;
            
    public:
           SmartImage();
           ~SmartImage();
           // copy constructor:
           SmartImage (const SmartImage& param) : surface(new SDL_Surface(param.content())) {}
           //access content
           const SDL_Surface& content() const {return *surface;}
           SDL_Surface *surface;
           void load(std::string filename);
           void copy_surface(SDL_Surface *target_surface);
};

#include"SmartImage.cpp"

the .cpp

SmartImage::SmartImage()
{
 surface=NULL;
 image_loaded = false;     
}

SmartImage::~SmartImage()
{
 SDL_FreeSurface(surface);      
}

void SmartImage::load(std::string filename)
{
    if(image_loaded == false)
    {
     surface = load_image(filename);
     image_loaded = true;
    }    
    else
    {
     SDL_FreeSurface(surface);
     surface = load_image(filename);
    }  
}

void SmartImage::copy_surface(SDL_Surface *temp_surface)
{
     if(image_loaded == true)
     {
      SDL_FreeSurface(surface);               
     }
 surface = SDL_DisplayFormat(temp_surface); 
 image_loaded = true;     
}

Share this post


Link to post
Share on other sites

You should check if SDL_DisplayFormat return NULL is that the case perhaps there is your error because should a other function need to access your surface but found only NULL could cause your problem. you should in general check if got SDL_Surface notequal NULL from the SDL functions.

Edited by exOfde

Share this post


Link to post
Share on other sites

The constructor function is called as soon as that object is created, so depending on where your object is created, this may occur before the SDL_Init of your program is even called. Depending on how you've set up your program, your constructor may be calling an SDL function before SDL has been initialized, which may be the source of your problem.

 

Edited for clarification due to a miswording.

Edited by Ludus

Share this post


Link to post
Share on other sites

The constructor function is called as soon as that object is created, so if your object is not dynamically allocated to memory during run time this will be before the main function of your program is even called. Depending on how you've set up your program, your constructor may be calling an SDL function before SDL has been initialized.

 

 

OMG I had no idea that copy constructor would run before main. I changed it to a pointer and now use the new keyword when I get into main. It stopped the crashing and after a few more hours of poking around I got it to work how I wanted to. So thank you, I feel like I need to research pointers more. I get the concept behind them but actually using them is giving me trouble. It seems I only run into problems with SDL_Surface tho.

 

 

#include"SmartImage.cpp"

What is that?

 

 

 

It's the .cpp file to the .h I don't see a problem with that line of code. I also listed the .cpp in my posts soooooooo what's up?

Share this post


Link to post
Share on other sites

 


#include"SmartImage.cpp"

What is that?

 

 

 

It's the .cpp file to the .h I don't see a problem with that line of code. I also listed the .cpp in my posts soooooooo what's up?

 

The problem is that you cannot use your SmartImage header in two or more files across your project. Each time you include SmartImage.h, it will also include SmartImage.cpp and all its definitions. If you include SmartImage.h in more than one file in your project, you will consequently have more than one definition of each of the class member functions and the linker will fail to do its job.

 

Add the file SmartImage.cpp to your project instead and compile it as a separate function. And, as the file is shown at the moment, it has to include the necessary headers as well in order to compile properly.

Share this post


Link to post
Share on other sites

Is it common practice to include the header file more then once? In my main file i just have .h after .h listed. I always thought this way was better since I used to do it like

a.h

a.cpp

b.h

b.cpp

c.h

c.cpp

 

Now a days I do

 

a.h

b.h

c.h

 

with the .cpp included from the .h

Share this post


Link to post
Share on other sites

OMG I had no idea that copy constructor would run before main. I changed it to a pointer and now use the new keyword when I get into main. It stopped the crashing and after a few more hours of poking around I got it to work how I wanted to. So thank you, I feel like I need to research pointers more. I get the concept behind them but actually using them is giving me trouble. It seems I only run into problems with SDL_Surface tho.

 

Just some advice, I recommend avoiding any use of SDL functions within constructors or destructors (the same issue will occur if you quit SDL before your destructors are called when the program closes). Simply create an initializing function and a clean up function which fulfill the same purpose that your constructors and destructors do now. Call the initializing function after you initialize SDL and before your game loop, and call the clean up function after your game loop and before you call SDL_Quit();

This way you can avoid needing to dynamically allocate your object after initializing SDL. You should avoid dynamically allocating anything unless it's absolutely required.

Share this post


Link to post
Share on other sites
Sign in to follow this  

  • Advertisement
×

Important Information

By using GameDev.net, you agree to our community Guidelines, Terms of Use, and Privacy Policy.

GameDev.net is your game development community. Create an account for your GameDev Portfolio and participate in the largest developer community in the games industry.

Sign me up!