Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

C++ Forward declaration and destructor

Two of my classes had to include each other. I made forward declarations instead, compilation is ok. One function of these classes is to call the destructor of the other. And that the compiler spits warnings at me, the destructor will not be called. What can I do? I can avoid this problem by creating another class for the function I need, avoiding the forward declarations but that would not be educative for me...

Here is my first class Header.h :

#ifndef H_HEADER
#define H_HEADER

#include "SDL/SDL.h"
#include "SDL/SDL_image.h"
#include "SDL/SDL_ttf.h"
#include <string>
#include <iostream>
#include <fstream>
#include <vector>
#include <sstream>
#include "DataFiles.h"

class Character; // forward declaration  Header <-> Character

class Header {

private:
 Character * ch; 
};

void cleanUp(std::vector <SDL_Surface*> & Vsurface, std::vector <TTF_Font*> & Vfont, std::vector <Character*> & Vchar);

// ... Other functions use in main.cpp

#endif

HEre is the Header.cpp:

#include "Header.h"
using namespace std;


void cleanUp(vector <SDL_Surface*> & Vsurface, vector <TTF_Font*> & Vfont, vector <Character*> & Vchar) {

 for(unsigned int i(0); i < Vsurface.size(); i++) 
  SDL_FreeSurface(Vsurface[i]);
 for(unsigned int i(0); i < Vfont.size(); i++)
  TTF_CloseFont(Vfont[i]);
 for(unsigned int i(0); i < Vchar.size(); i++)
  delete Vchar[i];

 TTF_Quit();
 SDL_Quit();

}

And here is the other Character.h class:

#ifndef H_CHARACTER
#define H_CHARACTER

#include <string>
#include <iostream>
#include <sstream>
#include <vector>
#include </usr/include/SDL/SDL_image.h>
#include </usr/include/SDL/SDL.h>
#include </usr/include/SDL/SDL_ttf.h>

#include "DataFiles.h"
#include "CharFrame.h"

class Header; // Forward declaration  Header <-> Character

class Character {

public:
 Character(std::string& dataPath);
 ~Character();
 // .. other functions 

private:

 Header * h;
 // ... other attributes
};
#endif

And here is my Character destructor:

Character::~Character() {

 cout << "Character " << m_name << " deleted.\n-----------------------------------\n" << endl;

}

So when my program ends, I call upon the Header's function "cleanUp()" giving it a vector of pointers to Characters. Every pointer should then be deleted through the Character's destructor ~Character(); However compilation gives me three warnings:

Header.cpp: In function ‘void cleanUp(std::vector<SDL_Surface*>&, std::vector<_TTF_Font*>&, std::vector<Character*>&)’:
Header.cpp:66:17: warning: possible problem detected in invocation of delete operator: [enabled by default]
Header.cpp:66:17: warning: invalid use of incomplete type ‘struct Character’ [enabled by default]
Header.h:27:7: warning: forward declaration of ‘struct Character’ [enabled by default]
Header.cpp:66:17: note: neither the destructor nor the class-specific operator delete will be called, even if they are declared when the class is defined

And once my program terminates, the character's destructor's message won't show up which means the destructor clearly isn't called.

What am I doing wrong with the forward declarations?

like image 791
Alexandre Toqué Avatar asked Oct 21 '25 05:10

Alexandre Toqué


1 Answers

Yep, that's what the (draft) standard says (§5.3.5.5);

If the object being deleted has incomplete class type at the point of deletion and the complete class has a non-trivial destructor or a deallocation function, the behavior is undefined.

(a non trivial destructor being one you defined yourself)

To fix it, just #include "Character.h" in header.cpp before invoking delete to allow the type to be completely declared.

like image 125
Joachim Isaksson Avatar answered Oct 23 '25 19:10

Joachim Isaksson



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!