36

I've been trying to include a structure called "student" in a student.h file, but I'm not quite sure how to do it.

My student.h file code consists of entirely:

#include<string>
using namespace std;

struct Student;

while the student.cpp file consists of entirely:

#include<string>
using namespace std;

struct Student {
    string lastName, firstName;
    //long list of other strings... just strings though
};

Unfortunately, files that use #include "student.h" come up with numerous errors like

error C2027: use of undefined type 'Student'

error C2079: 'newStudent' uses undefined struct 'Student'  (where newStudent is a function with a `Student` parameter)

error C2228: left of '.lastName' must have class/struct/union 

It appears the compiler (VC++) does not recognize struct Student from "student.h"?

How can I declare struct Student in "student.h" so that I can just #include "student.h" and start using the struct?

Eric Leschinski
  • 146,994
  • 96
  • 417
  • 335
wrongusername
  • 18,564
  • 40
  • 130
  • 214

7 Answers7

43

Try this new source :

student.h

#include <iostream>

struct Student {
    std::string lastName;
    std::string firstName;
};

student.cpp

#include "student.h"

struct Student student;
Software Engineer
  • 15,457
  • 7
  • 74
  • 102
Zai
  • 1,145
  • 7
  • 8
26

You should not place an using directive in an header file, it creates unnecessary headaches.

Also you need an include guard in your header.

EDIT: of course, after having fixed the include guard issue, you also need a complete declaration of student in the header file. As pointed out by others the forward declaration is not sufficient in your case.

baol
  • 4,362
  • 34
  • 44
  • Thanks for telling about the include guard... that fixed it. lol :) – wrongusername Apr 28 '10 at 20:50
  • 8
    -1. Although those are both true statements, I don't see how either of them would address the error messages reported in the question. – Rob Kennedy Apr 28 '10 at 21:21
  • 2
    @rob It wasn't an answer meant to be accepted ;) I just thought he needed the two advices. I believe that my answer, combined with the others, regarding the forward declaration, solved the problem. – baol Apr 29 '10 at 15:11
  • 1
    I was just about to comment on the "using" directive haha, good eye. – Jordan LaPrise Jan 28 '14 at 23:59
21

C++, how to declare a struct in a header file:

Put this in a file called main.cpp:

#include <cstdlib>
#include <iostream>
#include "student.h"

using namespace std;    //Watchout for clashes between std and other libraries

int main(int argc, char** argv) {
    struct Student s1;
    s1.firstName = "fred"; s1.lastName = "flintstone";
    cout << s1.firstName << " " << s1.lastName << endl;
    return 0;
}

put this in a file named student.h

#ifndef STUDENT_H
#define STUDENT_H

#include<string>
struct Student {
    std::string lastName, firstName;
};

#endif

Compile it and run it, it should produce this output:

s1.firstName = "fred";

Protip:

You should not place a using namespace std; directive in the C++ header file because you may cause silent name clashes between different libraries. To remedy this, use the fully qualified name: std::string foobarstring; instead of including the std namespace with string foobarstring;.

Eric Leschinski
  • 146,994
  • 96
  • 417
  • 335
18

Your student.h file only forward declares a struct named "Student", it does not define one. This is sufficient if you only refer to it through reference or pointer. However, as soon as you try to use it (including creating one) you will need the full definition of the structure.

In short, move your struct Student { ... }; into the .h file and use the .cpp file for implementation of member functions (which it has none so you don't need a .cpp file).

Edward Strange
  • 40,307
  • 7
  • 73
  • 125
4

You've only got a forward declaration for student in the header file; you need to place the struct declaration in the header file, not the .cpp. The method definitions will be in the .cpp (assuming you have any).

andand
  • 17,134
  • 11
  • 53
  • 79
  • hi @andand why would someone define a structure in a header file? Why not define a class directly? – Hani Goc Nov 06 '13 at 23:42
  • @HaniGoc, You declare the struct or class methods and members in the header so the class can be used in different places in the program. The class or struct method definitions (i.e. their bodies) are generally placed in .cpp files since if they are included in the header file and that header file is included in multiple .cpp files, the linker will complain of multiple definitions of those methods. The main exception is template definitions... those must be in the header file. That's just the way C++ works. – andand Nov 07 '13 at 04:36
  • @andand You've said that struct definition are generally placed in .cpp files while other answers have advised to place it in the .h file. I followed what you said and it worked for me but not sure why other answers have advised differently. Please clarify as I'm still learning these concepts. Thanks! – Ruchir Nov 20 '15 at 07:20
  • I think I've got the answer. If there are multiple .cpp files using the struct, it is better to define in .h file as the struct definition is accessible to any .cpp file which includes the .h file. – Ruchir Nov 20 '15 at 08:25
  • 1
    @Ruchir that's essentially correct, though you need to make sure there is a guard against including of the same header multiple times for a single .cpp file. It also gets a little complicated when there is a circular dependency between header files; forward declarations are generally the way to avoid such problems, but it's probably better to simply avoid the issue in the first place where feasible. – andand Nov 20 '15 at 16:20
2

Okay so three big things I noticed

  1. You need to include the header file in your class file

  2. Never, EVER place a using directive inside of a header or class, rather do something like std::cout << "say stuff";

  3. Structs are completely defined within a header, structs are essentially classes that default to public

Hope this helps!

Jordan LaPrise
  • 1,088
  • 1
  • 11
  • 20
1

You can't.

In order to "use" the struct, i.e. to be able to declare objects of that type and to access its internals you need the full definition of the struct. So, it you want to do any of that (and you do, judging by your error messages), you have to place the full definition of the struct type into the header file.

AnT stands with Russia
  • 312,472
  • 42
  • 525
  • 765