c++ struct and header files

Started by
6 comments, last by szecs 14 years ago
Hello. I was trying to define a struct in headerfile, but i couldn't link it to the cpp file. This is what i have:


typedef struct particle_object
{
  float x,y;
  int alive;
  float angle;
  float frame;
  float speed;
  float gravity;
  float time;
  float opacity;
  float velocity;

} particle_object;
particle_object particles[max_particles];


and i want to use "particle_object particles[max_particles]" in the cpp file, just like it was only 1 file. So how would you define this struct in the header, or how is it supposed to be linked?
Advertisement
Your problem doesn't have anything to do with the struct, your problem is that you're declaring a global variable in the header. e.g. if you put this in your header you'd get the same problem
int particles;

Headers are just copy&pasted into your CPP files when you compile, so your global variable 'particles' is being duplicated in multiple CPP files. When you try to link together your program, the linker doesn't know which one of these variables is the right one to use.

You can solve this problem by moving "particle_object particles[max_particles];" out of the header and into one single CPP file.

If you want to access this variable from other CPP files as well, then in your header you can write: "extern particle_object particles[max_particles];", which says that that variable exists somewhere externally, but doesn't actually create the variable.

[edit]Also your typedef struct name {...} name; code doesn't need to be that complex in C++ (the typedef struct idiom comes from C). You can instead just write "struct name {...};"

[Edited by - Hodgman on April 12, 2010 11:52:41 PM]
Thanks. I tried to add it as extern in the header.
So i have the struct declared in main.cpp, and in header file i have the particle_object declared as extern, then in effects.cpp i try to use the object.

"C:\cprojects\editor-particles\effects.h|51|error: `particle_object' does not name a type|" ?
Structure must still be declared in header file not in cpp file.
What do you mean when you say you have 'the struct declared in main.cpp'? Do you mean the "struct particle_object" bit isn't in the header any more? If so, then other CPP files can't possibly know what a particle_object is, so when you try to declare one, the compiler is telling you that it doesn't know what that is.

N.B.Each CPP file is compiled seperately, without knowledge of any other CPP files. When you include a header file, it's the same as copying and pasting it's contents into the CPP file.

Can you post your actual set up?

This might be of help: Organizing Code Files in C and C++
Ok let's see, i have:

main.cpp - this contains the main loop and function call().
#include <allegro.h>#include <OpenLayer.hpp>#include <loadpng.h>#include <string>#include "header.h"#include <windows.h>#include <GL/glut.h>#include <iostream>using namespace ol;using namespace std;int main() {   // SETUP    // Set up the program with all possible drivers //   Setup::SetupProgram();   // Set up the screen in windowed mode with the window size of 800 x 600 //   Setup::SetupScreen( 800, 600, WINDOWED );// LOADING ////////////////////////////////////////////////////////////////////////////////// VARIaBLES ////////////////////////////////////////////////////////////////////////////////// LOGIC ////////////////////////////////////////////////////////////////////////////////while( !key[KEY_ESC] ) {call();// RENDERING ////////////////////////////////////////////////////////////////////////////////Canvas::Fill( Rgba( 48, 170, 248, 255) );//END OF DRAW. Refresh the screen contents to show this frame ////////////////////////////////////      Canvas::Refresh();}return 0;}END_OF_MAIN()



Header.h - call() prototype
#ifndef LOAD_H_INCLUDED#define LOAD_H_INCLUDED#include <allegro.h>#include <OpenLayer.hpp>#include <loadpng.h>#include <string>using namespace ol;using namespace std;void call();#endif // LOAD_H_INCLUDED



header.cpp
#include "header.h"void call(){      particles.x = 111;      particles.y = 111;}


Now this is the struct that i want the call function to recognize:
struct test{  int alive;  int x;  int y;} test;test particles[100];



Where do i add this struct to make the call() function to recognize 'test particles[]' ?
Firstly: Headers are just copy&pasted into your CPP files when you compile
That means that when you compile main.cpp it copy&pastes the contents of your header like this:
#include <allegro.h>//duplicated below#include <OpenLayer.hpp>//duplicated below#include <loadpng.h>//duplicated below#include <string>//duplicated below//BEGIN: #include "header.h"#ifndef LOAD_H_INCLUDED#define LOAD_H_INCLUDED#include <allegro.h>//duplicated above#include <OpenLayer.hpp>//duplicated above#include <loadpng.h>//duplicated above#include <string>//duplicated aboveusing namespace ol;//duplicated belowusing namespace std;//duplicated belowvoid call();#endif // LOAD_H_INCLUDED//END: #include "header.h"#include <windows.h>#include <GL/glut.h>#include <iostream>using namespace ol;//duplicated aboveusing namespace std;//duplicated above

Secondly struct test{ ... } test; is wrong. It should just be struct test{ ... };.

Thirdly, when you say "this is the struct that i want the call function to recognize", you're showing code for two things - first you're making a new struct-type called test, then you're creating a new global variable of that type called particles.
Usually that first step (declaring the struct) would go in your header, and the second step (declaring the global variable) would go in your CPP file.
The rule is so simple (then you can work it out yourself):

Declaring the struct should be before you declare a variable of that type (obviously).
Declaring a variable should be before you use the variable (obviously) (or "re-declare" it using "extern" keyword, if you have to use "extern" with your own variables, that's a sign (for me at least) of a bad file/header structure design).

As others have already mentioned, type declarations (including stucts) should go into "whatever.h", variable declarations should go into "whatever.cpp"

This topic is closed to new replies.

Advertisement