instantiation in c++ - c++

First of all, I would like to notify you, I have definetly searched for answers about my following question, but im a complete newbie to C++.
I am coming from the luxurious life of C# and Java, now trying to pick up a thing or two about c++
The question is about instantiation.
I use code::block as my IDE of choice.
Currently I am just playing around with what in C# (which I'm actually quite familiar with and have written several applications in) is
2 classes
the class containing main and Person
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Models.Person;
namespace ConsoleApplication1
{
class Program
{
static void Main(string[] args)
{
Person person = new Person();
Console.WriteLine(person.getName());
}
}
}
and the person class:
namespace ConsoleApplication1
{
public class Person{
private string name = "Bob";
public string getName(){
return name;
}
}
}
(dont mind bad or right written syntax, its just to simulate what i want to achieve)
I want to achieve the same in C++
I have looked up, and learned about headers to some extent, and picked up a bit of the syntax. This is what I have right now.
main.cpp
#include <iostream>
using namespace std;
int main()
{
Person person;
cout << person->getName() << endl;
}
Person.h
#ifndef PERSON_H
#define PERSON_H
#include <string>
class Person
{
public:
Person();
virtual ~Person();
std::string getName();
protected:
private:
};
#endif // PERSON_H
player.cpp
#include "Person.h"
#include <string>
using std::string;
Person::Person()
{
//ctor
}
Person::~Person()
{
}
string Person::getName()
{
return name;
}
Considering the above code, I have multiple questions.
I never found a good source that showed me whether I should instantiate using Person person; or Person person = new Person();
Which one of the two is the one I'm supposed to use?
And another question I'm dying for is, do I define class members in the header file or in the class file?
Currently I'm recieving the following errors:
'person' was not declared in scope and expected ';' before person
I'm not nescesarily asking you to resolve my errors, I'll manage that upon recieving answers on my questions.

As larsmans said, Person person and Person *person = new Person() are result in the new Person instance being allocated in the stack/heap respectively.
What this means for you (and this is the answer to the "which should I use?" question) is that in the first case, the memory for the object is managed automatically (that's the good news). The bad news is that the lifetime of the object is also managed automatically, and you don't have any control over it. As soon as the person variable goes out of scope, the object is destroyed. Period.
In the second case (new), the object's lifetime is managed by you (it will exist until you do delete person). The bad news here is that the memory is also managed by you: if you don't ever do delete person, the memory allocated to that object will leak. It won't make any difference if you have no reference to person anywhere in scope anymore.
So if the lifetime is long enough for you, don't use a pointer. Otherwise, you will have to.
For class members:
They have to be declared in the header file; if you don't declare them and try to use them, you will get a compiler error.
They may optionally be defined in the header file; if not, you can define them in the .cpp file; if you don't define them anywhere and try to use them, you will get a linker error.
Generally definitions should go to the .cpp file, but it's OK if you define really short methods in the header.
Addendum
Of course there are plenty of details I didn't touch upon in this short answer. Here's a few important ones you might want to look into:
Using new/delete to manage memory can also give birth to lots of other problems apart from memory leaks; dangling pointers (which point to memory that has been released, and therefore cannot be used anymore -- this is essentially the "reverse" error than a memory leak) is probably #2 on the list.
Using some kind of smart pointer will help in achieving "C# semantics": whenever the last smart pointer to some memory goes out of scope, the memory will be released automatically on the spot (if it points to an object the destructor will run at this time; this is called deterministic destruction, C# does not have it and it has to try to emulate it with IDisposable). There are very good and mature smart pointers you can use in C++0x and Boost.
In C++, all types work like C# value types. If a takes up 2MB of memory and you do b = a, you just had the compiler populate a brand new 2MB of memory with a copy of a (and probably do a lot of extra work to achieve that). If that is not your intention, you need to store a pointer or a reference to a instead.

Person person will construct an object on the stack. Person *person = new Person will construct it in memory on the free store (heap; note the * because you need a pointer). This differs from C#, where you'd choose between struct and class to get either stack or heap allocation. In C++, these keywords have a different meaning. If you choose to allocate on the heap, then you must later delete the object manually.
Implement small, performance-critical methods that are not subject to change in the header. Put everything else in the implementation file.
(Please don't put a using directive at top-level in a header file.)

The equivalent of your C# code would be this:
#include <iostream>
#include <string>
class Person
{
std::string name;
public:
Person() : name("Bob"){}
std::string getName() { return name; }
};
int main()
{
//automatic variable; doesn't need new!
Person person;
std::cout << person.getName() << std::endl;
//pointer ; need to use new
Person *pPerson = new Person(); //it allocates memory!
std::cout << pPerson->getName() << std::endl;
delete pPerson; //it deallocates the memory!
}
Output:
Bob
Bob
See the online demo : http://ideone.com/cM0uU

The main distinction concerning Person is whether you want value
semantics or reference semantics---for entity objects, reference
semantics are necessary (since they preserve identity), but for
most others, value semantics are preferrable. In your example,
Person could easily be made to work with value semantics, but in
a more realistic case, it would depend on the role of the class
in the application.
Anyway, if you define value semantics, you do not (almost
never) allocate instances dynamically. You define them as local
variables, copying them as needed, and let the compiler take
care of the rest. You also make sure that copy, assignment and
the destructor do what you want---in modern C++, this is usually
the case, as your application level objects will be based on
lower level objects with copy constructors, assignment and
destruction which do the right thing, but this didn't used to be
the case, and it isn't always the case today. If you want
entity semantics, you have to decide what the lifetime of the
entity should be. (I'd say just as you would in other
languages, but many Java and C# programmers forget this. And
often get away with it. You won't get away with it, ever, in
C++.) Entity objects are normally created using new, and must
be destructed when their lifetime ends.
It's also good practice to ban copy and assignment of entity
objects (except maybe to provide a clone function) in C++.
Concerning the second point: the complete class definition must
be in a single place; you can't reopen the definition once
you've closed it with the last curly brace. This means that
member function declarations (but not the definitions) and
member data must be present in the class definition, in the
header file. It's best to put as little as possible in the
header file, however, and the definitions of the functions (the
implementation) normally belongs in the source file.
(There are exceptions to all of these rules, but they're a good
starting point.)

In the beginning of main.cpp you must also #include "Person.h".

In java, everything is a reference type, and so has to be instantiated using new, which creates a value type and returns a reference to it. In c++, the basic type is a value type, and a reference type similar to a java one looks like Person* person; You should really drop everything you know from java when going into c++ and start from the basics, it really can be very confusing to go from high to low level programming

If you're coming from C#, this explaination might be helpful:
In C++ the declaration/definition of a type doesn't say whether it is a "value type" or a "reference type". The only difference between 'struct' and 'class' is that members are private by default in 'class'. It's how you use it that determines this.
When you declare a Person, you are creating it as a "value type".
When you declare a Person*, you are creating a pointer (a reference type in C#) to a Person which normally is allocated on the heap with new. References (i.e. Person&) in C++ are like ref Person in C#.
As James points out in his comment, getting a good C++ book is your best bet.

The errors you're getting come from not using #include "Player.h" (assuming that's what you named the header file containing the declaration for the class Person since that's what your #define PLAYER_H suggests). After that, it'll complain because you're using person->getName() instead of person.getName(). The -> is used with pointers you should probably read up a bit more on this.
As for defining class members, if I understand the terminology correctly, you should declare them in your header file. They are then defined, often implicitly, in the constructor in your class file.
class MyClass {
int myVar; // Declare the variable
public:
MyClass(int inVar); // Declare the constructor function
};
And then in the class file:
MyClass::MyClass(int inVar) // Define the constructor function
: myVar(inVar) // Define the variable
{
}
Of course, you can do both in the header file and it's appropriate to do so sometimes.
class MyClass {
int myVar; // Declare the variable
public:
MyClass(int inVar) // Declare and define the constructor function
: myVar(inVar)
{}
};

Related

Get class pointer name from within its method?

Disclaimer: I'm fairly new to programming and my terminology may be way off. When I say "class pointer name", I mean the "A" in "myClass A" and in "A.Fill(...)".
I'm not sure how to formulate my question to make it as clear as possible, but let me try:
class myClass{
public:
// stuff
Fill(string msg)
{
// does stuff
cout << msg + "some extra text"; /*here I want to somehow get the name of the class pointer
which was used when calling this method, rather than having to manually pass it on as a string.*/
// more stuff
}
};
int main()
{
myClass A;
myClass B;
myClass C;
A.Fill("A");
B.Fill("B");
C.Fill("C");
}
This code is currently doing exactly what I want. However, I am wondering if it's possible to somehow get the class pointer name from within the method, rather than having to manually pass on a string argument every time?
I know that in macros I can use #A #B #C to get exactly that, but I'm uncertain how this would be applied for my code, and if it's possible at all.
You don’t want variable names, and you don’t want to be passing them in each time you call a method of the object.
You want object names. You need to give the A object a name, and then this name can be used by all of its methods.
Then, if you want convenience, instead of instantiating it as ClassA A("A");, you can have a macro that does it, like
#define ClassA_instance(var) ClassA var(#var)
Use:
ClassA_instance(A);
This way, you create an instance of that class that has the same name as the variable - but that’s pure convenience. You will find, soon enough, that you can give objects better names than what suffices for a variable name, especially if those objects are stored inside of other objects, where member variable names may be unwieldy due to eg. the m_ prefix. You can then also combine object names, so that object B inside of some object A will have its name set to “A.B” or similar. Tying the name to the name of a variable will have very limited uses.
ClassA has to store its name of course, and its constructor must accept the name. Eg.:
ClassA {
std::string m_objectName;
public:
ClassA(const std::string &name) : m_name(name) {}
ClassA(const char *name) : m_name(name) {}
...
};
You could factor out the naming aspect into a base class, although there’s so little code to it that I don’t see the sense in doing it - not unless you have other, better reasons to have a common base class.
Not even the compiler knows what variable name was used to call a member function. But you're right, you can use a macro to do what you want.
#define FILL(X) X.Fill(#X)
FILL(A);
FILL(B);
FILL(C);
No, there isn't a way to get a variable name automatically from with a class's function.
To do what you're asking for, it would have to be passed in.
Fill(string name, string msg)
{
//...
}
Perhaps you could come up with a macro that could be used in places where the function call is made that would streamline passing in the name.
myClass A;
CALLFUNCTIONANDPASSNAME(A, Fill("A"));
But in my option that just adds complexity for little value.
Furthermore there are lots of situation where trying to determine the variable name is going to be surprising or unhelpful. For instance:
myClass* p = new myClass[2];
p->Fill("...");
++p;
p->Fill("...");
Here Fill is called on two different instances, but the name of both would be "p". (Disregard the fact that this example does not show good memory management practices. I'm keeping it simple to only show what's relevant to this question.)
The better recommendation for class instances to have a name is to treat that as any other data you want a class to have - carry it in a member variable.
class myClass
{
string Name;
public:
myClass(string name)
{
Name = name;
}
void DoSomething()
{
cout << "My name is " << Name;
}
}
And then construct your instances with the desired name.
myClass fred("Fred");

I'm making a text-based rpg game but im keep getting "cannot call member function 'void monster::monsterDamage()' without object" message

I'm making a text-based RPG game but I'm keep getting cannot call member function 'void monster::monsterDamage()' without object message. Here is my code:
player.cpp
#include "player.h"
#include "monster.h"
void player::playerGetDamage()
{
pHealth -= monster::monsterDamage();
}
monster.cpp
#include "monster.h"
monster::monster(1)
{
mName="Rat";
mHealth=100;
mAttack=10;
mExp=50;
}
void monster::monsterGetDamage()
{
mHealth-=player::playerDamage();
}
void monster::pickMonster()
{
srand(time(NULL));
int a = rand() % 2 + 1;
if (a == 1)
{
monster(1)
}
if (a == 2)
{
monster(2)
}
}
I can't compile: I can't use mDamage in player.cpp or playerDamage() in monster.cpp. It says cannot call member function 'void monster::monsterDamage()' without object
Also, I wanted to choose random enemy with pickmonster() but I don't know how to use it. There is monster::monster(1) for an example but it seems it's wrong.
Since this is an object oriented program you must create a monster before a player can communicate with one. This means that you can't use the following code:
void player::playerGetDamage()
{
pHealth -= monster::monsterDamage();
}
It doesn't guarantee that a monster object of the "monster"-class exists. You can make sure that a player object knows that a monster exists by passing a monster object in the parameter.
void player::playerGetDamage(const monster& aMonster)
{
//Use object
pHealth -= aMonster.monsterDamage();
}
You'll get the same type of error in the monster-class too in this function:
void monster::monsterGetDamage()
{
mHealth-=player::playerDamage();
}
This can be corrected in the same way by passing a player object in the parameter but then you'll increase the dependency between the classes which might be a problem in the future. Perhaps it's time to reconsider where you handle the objects for the player and the monster?
and i wanted to choose random enemy with pickmonster() but i dont know how to use it there is monster::monster(1) for an example but it seems its wrong
Currently, your pickMonster-function in the monster-class is creating a new local monster-object inside itself. This means that if a monster object calls the function it will create another monster. I think that you want this functionality, to pick a monster, outside of the monster-class to get the behaviour that you want.
As others have stated, your biggest issue overall is that you don't know how to use classes and their objects. These concepts is pretty big for this answer so I suggest that you check out the mentioned ones by cmks; Class, object, member functions.
Further reading:
C++ Classes and Objects - TutorialsPoint
Classes (Part 1) - Cplusplus
The syntax you’re using, monster::monsterDamage(), would be correct for a static class function. That’s probably where you saw it used. Those are functions that don’t apply to any one monster in particular, but are just associated with the monster class in general. They don’t belong to any individual object of the class. One big difference between member functions that are and aren’t static is that a static member function does not get called with a this pointer, so you can’t use non-static data members or the this keyword inside one. Those are different from object to object, and static members are the same for all objects.
The static keyword is also used in a completely different way inside functions (to declare that a variable is persistent across all calls to that function, not a temporary that gets created when the function is called and destroyed when it returns) and a third completely different way outside either functions or class definitions (to declare that a symbol is only visible within this source file and files that #include it). Welcome to C++, where the standards committee would rather re-use an existing keyword than break old code by reserving a new keyword.
If you’re familiar with the <iostream> and <stdio.h> libraries, one example is that there’s a function in the standard library that makes them synchronize, std::ios_base::sync_with_stdio(). You don’t call it on cout, cin or cerr separately; there’s just one function that applies to the entire <iostream> library.
The other kind of class member has to be called like this:
monster foe;
player bar; // barian?
bar.mHealth -= foe.monsterDamage();
The mHealth member is not static, so it’s that player’s health, not all players’ health. But if you were keeping track of all damage done by all monsters in the game, that counter could be a static member of the monster class. How do you determine, inside your call, which monster is doing damage, though? Probably you want to pass that information in as a parameter, such as:
int player::playerGetDamage( monster& foe )
{
return pHealth -= foe.monsterDamage();
}
Then you call it with something like:
if ( bar.playerGetDamage(foe) < 1 )
bar.dies();

std::map::insert exception

This is another, "My code isn't working and i don't know why, " question i'm afraid. I just don't have enough knowledge of the stl to know why std::map::insert would throw an exception. If you know what cases it throws an exception, you can probably skip this wall of text and just answer. If you just desperately need some background on the issue, then have at it. I'll post my code and explain what is done, and i would be very grateful if all you with a better knowledge of the stl could explain what could be wrong with my call to insert.
I wrote an object awhile ago that i use occasionally as my go to factory object. It's main purpose is basically to take a string and store both the string and a "create new object function" pointer, so that in the end, you can call a function, pass a string, and if there is a valid registration for it, it returns a new instance of a derived object. Less talk, more code, here's what i got:
factory.h
#ifndef FACTORY_H
#define FACTORY_H
// library tools
#include <map>
#include <string>
// Simplified registration macros
#define DECLARE_DERIVED(T, base) static Factory<base>::DerivedRegister<T> reg;
#define DEFINE_DERIVED(T, base, s) Factory<base>::DerivedRegister<T> T::reg(s);
template<class base>
class Factory
{
protected:
template<class T>
static base * createT() { return new T;}
public:
typedef std::map<std::string, base*(*)()> map_type;
virtual ~Factory(){ }
static base * createInstance(const std::string & s)
{
if(!m_Map.count(s))
return nullptr;
std::map<std::string, base*(*)()>::iterator it = m_Map.find(s);
return it->second();
}
template <class T>
struct DerivedRegister;
protected:
static map_type m_Map;
};
template<class base>
template<class T>
struct Factory<base>::DerivedRegister : public Factory<base>
{
DerivedRegister(std::string const & s)
{
m_Map.insert(std::pair<std::string, base*(*)()>(s, &createT<T>));
}
};
#endif
here's a better explanation of what it does real quick. Let's say you have a base class, class A . and then you have any number of derived classes. I make a factory object somewhere templated to A, and then either create a derived register object manually, or use the macro at the top within the derived classes declaration to create a static registry object. Then you define it in the implementation and call it's constructor, passing in a string to be used to identify the object. using the factory member createInstance you can pass in a string identifier and have a derived object returned, pointed to by an A *.
example:
A.h
class A
{
};
A.cpp
// the map for this factory template has to be defined somewhere, as it is static
Factory<A>::map_type Factory<A>::m_Map;
b.h
#include <A.h>
class B : public A
{
// anywhere in declaration of derived B
DECLARE_DERIVED(A, B)
};
b.cpp
// just somewhere in cpp file
DEFINE_DERIVED(A, B, "B")
main.cpp
int main()
{
A * ptr;
Factory<A> factory;
ptr = factory.createInstance("B");
}
This object has worked for me in the past, mostly without a hitch. Now i'm doing a project a little more complicated. I've taken a liking to the data organization/ api design involved with game engines, and i'm just trying to implement a solution of cataloging, (but not instantiated) shaders, so that you have a whole list of the shaders you've programmed, but they will not be instantiated at run-time unless needed. That aside, this question actually has nothing to do with d3d11, or at least i hope not.
So here is what's going on. I have an object that represents a graphics-shader abstract class. All the shaders you wish to write must derive from this object. The you derive from and implement it's functions differently for all your different shaders.
let's call the base object "SYNC::D3D11Shader" in namespace sync and the derived shaders "ColorShader" "LightShader" and "TextureShader". Since i do not simply want to make an std::map of instances of these shaders within the rendering object, i make a factory within the rendering object like this.
D3D11Renderer.h
class D3D11Renderer
{
// many other members...
Factory<D3D11Shader> m_ShaderFactory;
// many other member...
};
D3D11Renderer.cpp
// define this templated classes map or you'll get undefined errors
Factory<SYNC::D3D11Shader>::map_type Factory<SYNC::D3D11Shader>::m_Map;
and then in the ColorShader i use the macros like so
D3D11ColorShader.h
class D3D11ColorShader : public SYNC::D3D11Shader
{
// ...lotsa members
DECLARE_DERIVED(D3D11ColorShader, SYNC::D3D11Shader)
// lotsa member...
};
D3D11ColorShader.cpp
// define the registery object with it's key here
DEFINE_DERIVED(D3D11ColorShader, SYNC::D3D11Shader, "ColorShader")
this all compiles fine, and where it throws it's exception is where i first call the registryObjects constructor in D3D11ColorShader.cpp, spefically at the insert call. the exception error is this:
Unhandled exception at 0x772315de in Syncopate.exe: 0xC0000005: Access
violation reading location 0x00000004.
So in reality, the question boils down to, when does std::map::insert throw an exception and why. I just knew everyone would be asking for some background on what i'm doing. Low and behold, a giant wall of text has appeared! All i really need is a hunch.
also should i or should i not tag d3d11, because the question doesn't really pertain to it?
Here's a problem:
std::map<std::string, base*(*)()>::iterator it = m_Map.find(s);
return it->second();
if the call to find fails (i,e. it can't find 's' in the map), then it will return m_Map.end(). Dereferencing that is a no-no.
My guess would be that this is due to the order of initialization of static variables. There is no way to control this order. So you are not guaranteed that your initialization:
Factory<A>::map_type Factory<A>::m_Map;
gets called before this initialization:
DEFINE_DERIVED(A, B, "B")
In this case the latter statement must be getting initialized first and so you map has not been allocated.
An alternative design pattern would control the initialization of the singleton factories. If you have an explicit Initialize function on each which creates the factory object then you can call this at the start of your main. E.g.
Factory.h
class Factory {
private:
static Factory* instance_;
public:
static Initialize(){instance_=new Factory;}
Factory* instance(){return instance_;}
}
Factory.cpp
static Factory* Factory::instance_ = NULL;
If you have a lot of factories you will probably want a single initialize function that initializes them all, and you will have to remember to add in the new factories as you create them.
Okay, i have actually been laboring over this error for about a day, and only now do i realize what is wrong.
problem 1:
the derived shaders header was never actually included anywhere throughout the project, and despite the fact that it never needs to be directly instantiated, it still has to be included somewhere so it can be linked and included in build.
problem 2:
interesting enough, just like combinatorial said, the initialization order was not done one after the other, but then looking over my old code, it seemed to initialize correctly before. what the difference here was, i put the factory of the derived objects within a different object then the base class. what i used to do was declare a static function and static factory within the base class so that you could instantiate any of it's registered derived classes from the base class itself. When the factory is included within the base class instead, and instantiation is done through a static function, the initialization order of all the statics seems to be constently in order ( not sure if this is always true). It runs fine now after changing this.
so now, my answer, you can get operating system exceptions like this for trying to use references to objects that were never actually included anywhere in your project. I don't have a very good knowledge of compilers or linkers to tell you why it seemed to compile fine, despite this object never being included. If someone wants to extend my answer, please.
I use MSVC++ 2010 express if that pertains to this predicament.

c++ difference between std::string name and std::string &name

I have a lib.h, lib.cpp and test.cpp. I would like to ask what is better?
lib.h
class c
{
std::string name;
}*cc;
lib.cpp
{
std::cout << "the name is:" << name << std:: endl;
}
test.cpp
main()
{
c tst;
tst.name="diana";
}
What should I use? std::string name or std::string *name? How can i work with &name, how will my code change and which one of these 2 methods is the best one?
First, I hardly believe your code will compile while in your main you try to get access to private data member name.
About &. It is really hard to define where to start. In short std::string &name is called reference to object of type std::string. Reference is somehow an alias to some other object. The main feature is, that you always have to initialize refence to object while creating and you can't reinitialize reference to point to another object. More about this feature you can read in C++ FAQ
EDIT
Generally you can declare public, protected and private members of your class in with arbitrary ordering:
class MyClass {
//here goes private members when working with class
//and public when working with structs
public:
//here goes public members
protected:
//here goes protected
private:
//here goes private
public:
//here goes public again
};
Ordering of members declaration is actually code policy question. For example, google style guide recommends to put all public members before private.
About hiding function members (not necessary private). You actually can't hide function member declaration, but there are several ways to "hide" implementation, but I am not sure that it's the definition of hiding you are talking about. But you can check PImpl idiom. This requires understanding of pointers so I advice you to start with them first.
Small code sample for working with pointer to string:
#include <iostream>
#include <string>
class MyClass {
public:
std::string *pstr;
};
int main() {
std::string str("test");
MyClass myObj;
myObj.pstr = &str;
std::cout << myObj.pstr->c_str() << std::endl;
}
std::string & name; is a reference. You'll need to initialize it in the constructor, so it actually refers to something. What it refers to must exist as long as your c instance exists. It's not the right solution for this.
std::string name; is an actual variable, use this.
std::string &name is "only" a reference to a string (a bit like a pointer). Because the name definitely belongs to the class c, I think it would make sense to have an instance there.
References are put to good use when passing instances around (to avoid copying).
const std::string&
is reference to a std::string, it is very important to understand the implications of that with respect to the lifetime of variables. Once the referenced variable goes away, the reference is no longer valid, and this is a very common way to f*ck up for beginning C++ programmers.
YMMV, Pick up a good tutorial first, and meanwhile, don't use references unless you know why and what you're doing
Good luck
I'd use: string name; because string* name is just a pointer that needs to be given a value, and then I'd have to think of a way to clean it up later all by myself, and string& name, would be just a name that again has to be initialized.

What is wrong with this c++ typedef?

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...
};
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.
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.
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.)
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.