views:

329

answers:

4

This is a piece of my code, I have more class like MathStudent, ArtStudent, etc. which inherits Student class. When I tried to compile, it says "forbids declaration of `vector' with no type," what is the problem here? thanks

class Student {
public:
    typedef vector<Student> Friends; // something wrong here?

    virtual unsigned int getId() = 0;

    //some more pure virtual functions...
};
+10  A: 

You can't use a class which is not yet defined. You could however use a pointer to that class.

Your specific error right now is probably that you forgot to #include <vector> or do using namespace std;. But as soon as you solve that, you'll need my first advice.

John Zwinck
Whoa there. You should **never** put a using directive in a header file.
rlbond
Good point. But nobody said this was in a header file. If it is, then you are right: "using" should not be used at the global scope, but rather `std::vector`.
John Zwinck
Why can't I put using namespace std in header file?
derrdji
@derrdji - don't put `using namespace std` in a header because then you bring in the `std` namespace for anything that includes the file (whether they know it or not, because it may be included indirectly). You'll be polluting the namespace needlessly, and this can cause problems for users who don't expect it.
Michael Burr
+2  A: 

Vectors store items by value, not by reference. If you want to be able to store MathStudent, ArtStudent, and the like, you should think about using a vector of (smart) pointers to Student instead:

typedef vector<shared_ptr<Student> > friends;

(where shared_ptr is either std::tr1::shared_ptr or boost::shared_ptr, depending on whether your C++ system supports TR1.)

Chris Jester-Young
A: 

You need to include the header for vector and consider the namespace.

Eg:

#include <vector>

using namespace std;

...rest of your code here...

should compile just fine.

tim
+4  A: 

One problem with the typedef is that class Student is an abstract class, so it cannot be default constructed, which is required for types that vectors can be composed of.

Another issue (say you removed the fact that class Student is abstract) might be that the class isn't fully defined. You can, in fact, declare a typedef for a vector<> with an incomplete class, but you wouldn't be able to actually use the typedef until the class was fully defined - except to declare pointers or references to the type.

In both a cases you may need to think about the class's overall design - you may want to have a vector<Student*> instead so the vector can hold any type of student (using pointers since it can't hold an actual abstract Student object). As others have mentioned using smart pointers (but not std::auto_ptr<>) would help with managing the lifetimes of object pointed to by the vector.

Michael Burr