Sign in to follow this  
Plasmarobo

H file madness.... again

Recommended Posts

Agghh! Well, I yet again have a problem that I cannot fiqure out. I just reorganized a struct into it's own file. The new file works quite well, but the old file has no dependance on the struct, yet it somehow killed itself. What do I do ta fix it? Errors: ompiler: Default compiler Building Makefile: "C:\Dev-Cpp\projects\1\Makefile.win" Executing make... make.exe -f "C:\Dev-Cpp\projects\1\Makefile.win" all g++.exe -c Equipment.cpp -o Equipment.o -I"lib/gcc/mingw32/3.4.2/include" -I"include/c++/3.4.2/backward" -I"include/c++/3.4.2/mingw32" -I"include/c++/3.4.2" -I"include" In file included from Equipment.cpp:8: item.h:19: error: `string' does not name a type item.h:35: error: variable or field `Save' declared void item.h:35: error: expected `;' before '(' token item.h:37: error: expected `;' before '(' token item.h:46: error: ISO C++ forbids declaration of `vector' with no type item.h:46: error: expected `;' before '<' token item.h:52: error: expected `,' or `...' before '&' token item.h:52: error: ISO C++ forbids declaration of `string' with no type item.h:56: error: expected `,' or `...' before '&' token item.h:56: error: ISO C++ forbids declaration of `string' with no type In file included from Equipment.cpp:9: Equipment.h:32: error: variable or field `Save' declared void Equipment.h:32: error: expected `;' before '(' token Equipment.h:33: error: expected `;' before '(' token Equipment.cpp:51: error: no `void tEquipment::Save(std::ostream&)' member function declared in class `tEquipment' Equipment.cpp:63: error: no `bool tEquipment::Load(std::ifstream&)' member function declared in class `tEquipment' make.exe: *** [Equipment.o] Error 1 Execution terminated items.h
//Item structure .h
#include <fstream>
#include <iostream>
#include <string>
#include <vector>
//This is the structure of an Item
//Created some time in march
//Austen Higgins-Cassidy




#ifndef _ITEM_H_
#define _ITEM_H_


struct tItem
{
	string name;
	int type;
    int id;
	int wieght;
	int value;
	int para1;
	int val1;
	int para2;
	int val2;
	bool key;
    tItem();

	~tItem();

	tItem(const tItem& RHS);

	void Save(ostream& fOut);

	bool Load(ifstream& fIn);
	
};



class ItemsData
{
private:
vector<tItem> ItemDataBase;

public:
	ItemsData();
	~ItemsData();

	bool LoadItems(const string& filename);
	bool SaveItems(const std::string filename);
	void DisplayItems();

        void MakeItem(const string& iname, int iwieght, int ival, int type, bool key = false);

};


 
#endif



items.cpp
//Items cpp
//Expantions for items.h
//Austen Higgins-Cassidy
// 4/1/2006

#include <fstream>
#include <iostream>
#include <string>
#include <vector>
#include <ctime>
using namespace std;
#include "item.h"




	ItemsData::ItemsData()
	{
ItemDataBase.clear();
	}

	ItemsData::~ItemsData()
	{
ItemDataBase.clear();
	}


	// Load items based on a filename and returns true or false of the
	// success.
bool ItemsData::LoadItems(const string& filename)
	{
	   	ifstream fobj;
		fobj.open(filename.c_str());
		if(fobj.fail() || !fobj.is_open())
			return false;
	//clear IDB
	ItemDataBase.clear();
    
    	bool done = false;
		while(!done)
		{
			
			tItem temp;
			done = !temp.Load(fobj);

			
			if(!done)
			{
				ItemDataBase.push_back(temp);
							string buf;
				getline(fobj, buf, '\n');
			}
		}
		fobj.close();
		return true;
	}

	// Save all of the items but keep them in the vector
	bool ItemsData::SaveItems(const std::string filename)
	{
		ofstream fptr;
		fptr.open(filename.c_str());
		if(fptr.fail() || !fptr.is_open())
			return false;
		
		
        for(size_t x = 0; x < ItemDataBase.size(); x++)
		{
			ItemDataBase[x].Save(fptr);
		}
        fptr.close();
		return true;
	}

	void ItemsData::DisplayItems()
	{
		for(size_t x = 0; x < ItemDataBase.size(); x++)
		{
			ItemDataBase[x].Save(cout);
			cout << endl;
		}
	}

 void ItemsData::MakeItem(const string& iname, int iwieght, int ival, int type, bool key)
	{
		tItem nItem;
		nItem.id = 1+(int)ItemDataBase.size();
		nItem.name = iname;
		nItem.wieght = iwieght;
		nItem.value = ival;
		nItem.type = type;
        nItem.key = key;
		ItemDataBase.push_back(nItem);
	}



      




       
      




tItem::tItem()
	{
		name.clear();
		type = 0;
		id = -1;
		wieght = 0;
		value = 0;
		para1 = 0;
		val1 = 0;
		para2 = 0;
		val2 = 0;
		key = 0;
	}


	// We make a default destructor due to the C++ rule of 3
tItem::~tItem()
	{
		// Nothing to do
	}

	// We make a copy constructor due to the C++ rule of 3
tItem::tItem(const tItem& RHS)
	{
		name = RHS.name;
		type = RHS.type;
		while(id <= RHS.id)
		{
        srand(time(0));
        id = rand();
        }
        
		wieght = RHS.wieght;
		value = RHS.value;
		para1 = RHS.para1;
		val1 = RHS.val1;
		para2 = RHS.para2;
		val2 = RHS.val2;
		key = RHS.key;
	}
// For now, when you are developing your game or whatever, it is 
	// IMPORTANT to make sure that you know the file being written to
	// files is clear, concise, and correct! Because of this, you will
	// always want to save your data in text format so you can easily
	// verify and validate it. When you take this approach, you can
	// easily see if there is a bug in your code or in the data files
	void tItem::Save(ostream& fOut)
	{
		fOut << name << endl;
		fOut << type << " ";
		fOut << id << " ";
		fOut << wieght << " ";
		fOut << value << " ";
		fOut << para1 << " ";
		fOut << val1 << " ";
		fOut << para2 << " ";
		fOut << val2 << " ";
		fOut << key << endl;
	}

	// Same as what I said for the save function. When you are ready for
	// deployment, you can make a new Save/Load function that will work
	// in binary format. But for now, use text =)
	// I also made this a bool to make sure we can load data from the file
	bool tItem::Load(ifstream& fIn)
	{
		if(!getline(fIn, name))
			return false;
		fIn >> type;
		fIn >> id;
		fIn >> wieght;
		fIn >> value;
		fIn >> para1;
		fIn >> val1;
		fIn >> para2;
		fIn >> val2;
		fIn >> key;
		return true;
	}


Equipment.h (the new file)
//Equipment.h
//This file will initilize the equipment object
//It was originally in item.h, but I need to make use of the objects in that, and this was simpler.
//Austen Higgins-Cassidy
// 4/3/2006

#include <fstream>
#include <iostream>
#include <string>
#include <vector>
#include "item.h"

#ifndef _EQUIPMENT_H_
#define _EQUIPMENT_H_



struct tEquipment
{
       tItem *head;
       tItem *body;
       tItem *rarm;
       tItem *larm;
       tItem *rhand;
       tItem *lhand;
       tItem *boots;
       tItem *acc;
       tEquipment();
       ~tEquipment();
       tEquipment(const tEquipment& RHS);
       
       void Save(ostream& fOut);
       bool Load(ifstream& fIn);
};


#endif

and finally Equipment.cpp
//Expantion file for Equipment.h
//Austen Higgins-Cassidy
// 4/3/2006
#include <fstream>
#include <iostream>
#include <string>
#include <vector>
#include "item.h"
#include "Equipment.h"

using namespace std;

tEquipment::tEquipment()
       {
        head = NULL;
        body = NULL;
        rarm = NULL;
        larm = NULL;
        lhand = NULL;
        rhand = NULL;
        boots = NULL;
        acc = NULL;                   
       }
                            
       tEquipment::~tEquipment()
       {
        delete head;
        delete body;
        delete rarm;
        delete larm;
        delete lhand;
        delete rhand;
        delete boots;
        delete acc;                               
       }
       
       tEquipment::tEquipment(const tEquipment &RHS)
       {
       head = RHS.head;
       body = RHS.body;
       rarm = RHS.rarm;
       larm = RHS.larm;
       lhand = RHS.lhand;
       rhand = RHS.rhand;
       boots = RHS.boots;
       acc = RHS.acc;
                                
       }
       
       void tEquipment::Save(ostream& fOut)
       {
      	fOut << head->id << " ";
		fOut << body->id << " ";
		fOut << rarm->id << " ";
		fOut << larm->id << " ";
		fOut << rhand->id << " ";
		fOut << lhand->id << " ";
		fOut << boots->id<< " ";
		fOut << acc->id << endl;		
       }
       
       bool tEquipment::Load(ifstream& fIn)
       {
         	int idtag;
        head = NULL;
		body = NULL;
		rarm = NULL;
		larm = NULL;
		rhand = NULL;
		lhand = NULL;
		boots = NULL;
		acc = NULL;
		return true;   
       }

Thank you for helping me out.... I should know how to fix this, since I have had errors like this sooo many times.... but it seems something different creates that same error again and again.... :/

Share this post


Link to post
Share on other sites
First thing I see is that in item.h, you do not have the statement "using namespace std;", and thus it isn't recognizing string and vector as valid types. You could put the using statement at the top of item.h, but that isn't an advisable solution. It's bad to put using statements in header files, because then anyone that includes the header is also including the using statement without knowing it, or at least without wanting it. I believe this is often referred to as namespace pollution.

The more correct method is to use "std::" (or whatever else the appropriate namespace is) before all uses of the types from the namespace. So instead of just directly writing "string", write "std::string". And "std::vector" instead of "vector". In a cpp file, however, feel free to go ahead and use the using statement, and drop the "std::". I personally always use "std::", but in this context it's probably more of a personal preference.

[edit]The "std::" prefix goes for *stream types as well.[/edit]
[edit]I didn't notice that you were already aware of the existence of "std::". Oops. But the point that it needs to be used in the headers still applies.[/edit]

Share this post


Link to post
Share on other sites
The reason why your getting these errors are this

In Items.h you are using string, vector...

In Items.cpp, you put in using namespace std before you include the Items.h file so as far as your Items.cpp file is concerned everything is fine.

Now... In Equipment.cpp you do not include the line using namespace std before the inclusion of Items.h

The Fix...

You need to prefix all of your STL stuff with std:: just like agony was saying because you do not want the using namespace xxx in a header file

Share this post


Link to post
Share on other sites
Quote:
Original post by Tradone
right under all the #include files
add

#using namespace std;

that line.
you will get rid of most errors.


This will give you more errors...

It is:
using namespace std;
#using is a .NET thingy for importing .NET code

and you should stick that line of code in before the #include files (that use the STL functions) because it is in those include files that there are STL functions and they won't know about the using namespace std if you put them after the include files.

Prefixing STL functions in header files with std:: is my method of choice.

Share this post


Link to post
Share on other sites
Quote:
Original post by Adam Hamilton
It is:
using namespace std;
#using is a .NET thingy for importing .NET code

and you should stick that line of code in before the #include files (that use the STL functions) because it is in those include files that there are STL functions and they won't know about the using namespace std if you put them after the include files.


The first part is correct, the second is not. The "using namespace" directive applies to the following code, expanding the default namespace to include, for instance, std.

For instance:

#include <string>

string g_string; //compiler error.

using namespace std;
string g_string2; //compiles fine.

Share this post


Link to post
Share on other sites
Guest Anonymous Poster
Quick question in response to C++ .h/.cpp files: Is it a bad habit to code the class methods within the class in the .h file instead of making a .cpp file?

Share this post


Link to post
Share on other sites
Quote:
Original post by Anonymous Poster
Quick question in response to C++ .h/.cpp files: Is it a bad habit to code the class methods within the class in the .h file instead of making a .cpp file?


Not as such no, all it does is implicitly state those functions as inlined, but the compiler will happily ignore that to its heart's content. If you've got a few small accessors/mutators, then feel free to throw them in the class definition. The implicit inline will probably be a benefit. Long functions should probably be taken out though, to improve readability.

Also, if you want your code to not be open to everyone who might include your headers, then you'll have to put it in the source files (to which the people will need to link to your .lib file).

Share this post


Link to post
Share on other sites
Not sure that this is the exact problem but this may be something that I am remembering from my C days.

typedef struct
{
...
} tItem;
And as some other people said you need to do either:

using std::vector;
using std::string;
or (for all of the instances of each.)

std::vector<tItem>
std::string
I would also suggest the following to make some of your life simpler when managing the vector operations.

typedef std::vector<tItem> tItemVector;

tItemVector::iterator
instead of

std::vector<tItem>::iterator
Just some suggestions! Happy coding!

Share this post


Link to post
Share on other sites
Quote:
Original post by BeanDog
Quote:
Original post by Adam Hamilton
It is:
using namespace std;
#using is a .NET thingy for importing .NET code

and you should stick that line of code in before the #include files (that use the STL functions) because it is in those include files that there are STL functions and they won't know about the using namespace std if you put them after the include files.


The first part is correct, the second is not. The "using namespace" directive applies to the following code, expanding the default namespace to include, for instance, std.


I am not sure why you say the second is not... Could you please explain?

Share this post


Link to post
Share on other sites
Simply, you don't need to put 'using namespace std;' *before* including the headers, because they are defining stuff *inside* the namespace - they're already quite well aware of it.

A using-declaration applies to the remainder of the translation unit. This is why you don't want to put them in headers: they woul apply also to files that #included them, and thus users of your header wouldn't have the option *not* to use the namespace.

Share this post


Link to post
Share on other sites
Quote:
Original post by Adam Hamilton

and you should stick that line of code in before the #include files (that use the STL functions) because it is in those include files that there are STL functions and they won't know about the using namespace std if you put them after the include files.


Now... Have a look at Equipment.cpp in the first posting of this thread and have a look at
1. The line where Item.h and Equipment.h is included
2. The line where using namespace std is

Now look in both items.h and equipment.h and from the compilers perspective do the identifiers string, ostream, ifstream and vector exist?

My answer is no because as far as the compiler is concerned, the std:: scope has not being brought into existance because the using namespace std; line appears after the 2 include files which was why I was saying before that the using namespace std; line should be put in before the 2 include files

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

Sign in to follow this