Save vector objects in a file

closed account (DEhqDjzh)
Hi, my older question http://www.cplusplus.com/forum/general/238988/ was about creating an object factory. But now I have a problem I must save objects in vector<GameObject> to a file called Objects.dat. How can I do that?
Last edited on
Um... the same way as you'd write any other data to a file?

You'll need to decide what structure and format you want the file to have. But there's nothing fundamentally different about writing the value of an object's data member to a file, from writing the value of any other variable to a file.

You might want to look at overloading the streaming operators << and >> for your class. That can make life easier.
Last edited on
closed account (DEhqDjzh)
@MikeyBoy can you post the pseudo code?
1
2
3
4
5
6
for (each element in vector)
{
  myFile << first_data_member_of_element
  myFile << second_data_member_of_element  
  // etc
}


Or, if you've overloaded the << operator:

1
2
3
4
for (each element in vector)
{
  myFile << element
}


In other words, to access each element of the vector, you do exactly the same thing as you'd do to access the elements of any vector, and to write the values to the file, you do exactly the same thing as you'd do to write any other values to the file.

There's nothing magical about putting objects in vectors, that makes them work differently from vectors of, say, integers.

There's nothing magical about putting objects in vectors, that makes accessing the members of the object different from accessing the members of an object that isn't in a vector.

There's nothing magical about members of objects that makes writing them to file any different to writing any other values to file.
Last edited on
Personally I don't usually think much about the format but just make sure to read everything in the same order that I write. It has worked good for simple things that I have done but if your objects are complicated and share objects though pointers and such you might have to think more carefully how to make it work.

Here are some oversimplified pseudo code to demonstrate what I mean.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
void save(const vector<GameObject>& objects)
{
	writeInt(objects.size());
	for (const GameObject& obj : objects)
	{
		save(obj);
	}
}

void save(const GameObject& obj)
{
	writeInt(obj.x);
	writeInt(obj.y);
	writeString(obj.name);
}


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
void load(vector<GameObject>& objects)
{
	std::size_t numberOfObjects = readInt();
	objects.resize(numberOfObjects);
	for (GameObject& obj : objects)
	{
		load(obj);
	}
}

void load(GameObject& obj)
{
	obj.x = readInt();
	obj.y = readInt();
	obj.name = readString();
}


Don't take any of this too literally. You probably want to pass some kind of stream objects to the functions that you call the read and write functions on. You might prefer to have the save and load functions as member functions. You should also check for errors in the load functions. This is actually my favourite situation were I like to use exceptions.

But the important point that I want to make here is that each load function reads exactly as much data as the corresponding save function writes, and it does so in exactly the same order. When you write a save function you need to think about how the load function is going to read the data. If I had just saved each object, without saving how many objects there are, it wouldn't have been possible for the load function to know how many objects to load.
Last edited on
closed account (DEhqDjzh)
@MikeyBoy visual studio says "no operator "<<" matches these operands" so what now ?
Matches what operands? Without seeing your code, how can I possibly know what's wrong with it?
closed account (E0p9LyTq)
visual studio says "no operator "<<" matches these operands" so what now ?

Likely you will need to write an overloaded << operator for serializing the output of the object.

Hard to tell you what to do beyond a simple guess since you have provided no code.
closed account (DEhqDjzh)
Save code
1
2
3
4
5
6
7
8
9
10
11
12
13
vector<GameObject> obv;
				ofstream save;
				kayit.open("objects.dat");
				for (int i = 0; i < obv.size(); i++)
				{
					save << obv[i] << endl; // error 

				}


				
				
				save.close();

Must I save every variable on Gameobject manually?
Last edited on
Must I save every variable on Gameobject manually?
Only the ones that need to be saved, that depends on your code.

The overloaded operator should look like this:
1
2
3
4
5
ostream& operator<<(ostream& oss, const GameObject& obj)
{
  // you code here
  return oss;
}

Is there a possibility that classes derived from GameObjects will be stored in the vector?
If yes then it might be a better idea to use virtual functions to save the object so it can be overriden.
Remember where I said:

Or, if you've overloaded the << operator:
?

The pseudocode I posted showed you two ways of doing it, one for writing each data member individually, and one for what you could do if you overload the streaming operators.
Last edited on
closed account (DEhqDjzh)
@Thomas1965 Can you give an example of how to overload << operator with Gamobject?

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
// Example program

#include <string>
#include <iostream>

struct GameObject {
    int foo;
    std::string bar;
};

std::ostream& operator<<(std::ostream& os, const GameObject& obj)
{
    os << obj.foo << " " << obj.bar;   
    return os;
}

int main()
{
    GameObject obj { 42, "hi" };
    
    
    std::cout << obj << std::endl; // could be a file stream!
}
closed account (DEhqDjzh)
Thank you :)
Topic archived. No new replies allowed.