Reputation: 189
My actual question is in the bold text below, but here's the context of my problem:
I'm trying out Boost::serialization for saving and restoring a player's state. I read the tutorial at http://www.boost.org/doc/libs/1_56_0/libs/serialization/doc/tutorial.html#simplecase, but I'm not sure how
boost::archive::text_iarchive
works.
I'm working on the assumption that the following lines
boost::archive::text_iarchive inArchive(playerfile);
inArchive >> target;
will initialize the target according to the playerfile's corresponding textfile?
I'm wrote the following functions with that assumption:
bool SavePlayerState(Player *target)
{
std::string fileName = (target->name) + ".playerfile";
std::ofstream playerfile(fileName);
if(!playerfile.is_open())
{
s_al_show_native_message_box(display, "SAVE FAILURE", "SAVE FAILURE", fileName + "could not be created/opened.",
NULL, ALLEGRO_MESSAGEBOX_ERROR);
return false;
}
boost::archive::text_oarchive outArchive(playerfile);
outArchive << target;
return true;
}
bool LoadPlayerState(std::string playerName, Player *target)
{
std::string fileName = playerName + ".playerfile";
std::ifstream playerfile(fileName);
if(!playerfile.is_open())
{
s_al_show_native_message_box(display, "LOAD FAILURE", "LOAD FAILURE", fileName + "could not be found/opened.",
NULL, ALLEGRO_MESSAGEBOX_ERROR);
return false;
}
boost::archive::text_iarchive inArchive(playerfile);
inArchive >> target;
return true;
}
They are called in main() for testing purposes:
int main(int argc, char *argv[])
{
//...
player = new Player(5,5); // There is a Player*player; declared elsewhere
LoadPlayerState("player", player); //Load the file with this name, target is player object
beings.push_back(player);
//The game's operations...
SavePlayerState(player);
delete player;
//...
return 0;
}
SavePlayerState(player); works as I expected, and I find that player.playerfile has been created in my directory. But LoadPlayerState("player", player); gives me the following error:
C:\Development\Libraries\boost\boost\serialization\access.hpp|132|error: no matching function for call to 'Player::Player()'|
I don't know why the constructor should have problems, or why Save works and not Load. I'm not trying to make a new Player object, just shape the existing target Player according to the archive. What do I need to change in order to make this work?
My player class:
#ifndef PLAYER_H_INCLUDED
#define PLAYER_H_INCLUDED
#include "being.h"
#include "extfile.h"
#include <boost/archive/text_oarchive.hpp>
#include <boost/archive/text_iarchive.hpp>
#include <boost/serialization/base_object.hpp>
#include <boost/serialization/vector.hpp>
class Player: public Being
{
friend class boost::serialization::access;
template<class PlayerArchive>
void serialize(PlayerArchive & par, const unsigned int version)
{
par & boost::serialization::base_object<Being>(*this);
par & active;
//par & various things
}
public:
Player(bool savedPlayer);
Player(int spawnXCell, int spawnYCell);
~Player();
//Functions
};
//Prototype to the save and Load state functions mentioned previously are found here.
#endif // PLAYER_H_INCLUDED
Here is my complete build messages log, if it helps:
>||=== Build: Debug in Roguelike (compiler: GNU GCC Compiler) ===| >C:\Development\Libraries\boost\boost\serialization\access.hpp||In instantiation of 'static void boost::serialization::access::construct(T*) [with T = Player]':| >C:\Development\Libraries\boost\boost\serialization\serialization.hpp|93|required from 'void boost::serialization::load_construct_data(Archive&, T*, unsigned int) [with Archive = boost::archive::text_iarchive; T = Player]'| >C:\Development\Libraries\boost\boost\serialization\serialization.hpp|158|required from 'void boost::serialization::load_construct_data_adl(Archive&, T*, unsigned int) [with Archive = boost::archive::text_iarchive; T = Player]'| >C:\Development\Libraries\boost\boost\archive\detail\iserializer.hpp|341|required from 'void boost::archive::detail::pointer_iserializer::load_object_ptr(boost::archive::detail::basic_iarchive&, void*, unsigned int) const [with Archive = boost::archive::text_iarchive; T = Player]'| >C:\Development\Projects\Roguelike\Roguelike\player.cpp|76|required from here| >C:\Development\Libraries\boost\boost\serialization\access.hpp|132|error: no matching function for call to 'Player::Player()'| >C:\Development\Libraries\boost\boost\serialization\access.hpp|132|note: candidates are:| >C:\Development\Projects\Roguelike\Roguelike\player.cpp|8|note: Player::Player(int, int)| >C:\Development\Projects\Roguelike\Roguelike\player.cpp|8|note: candidate expects 2 arguments, 0 provided| >C:\Development\Projects\Roguelike\Roguelike\player.cpp|3|note: Player::Player(bool)| >C:\Development\Projects\Roguelike\Roguelike\player.cpp|3|note: candidate expects 1 argument, 0 provided| >C:\Development\Projects\Roguelike\Roguelike\player.h|12|note: Player::Player(const Player&)| >C:\Development\Projects\Roguelike\Roguelike\player.h|12|note: candidate expects 1 argument, 0 provided| ||=== Build failed: 1 error(s), 5 warning(s) (0 minute(s), 4 second(s)) ===|
Thanks very much. If any other information is required, I will append it.
Upvotes: 2
Views: 2194
Reputation: 393134
In addition to what Joachim said, in some cases you will not be able to make a type default-constructible (especially when you're adding non-intrusive serialization to types from a 3rdparty library).
In that case learn about the load_construct_data
customization point:
This mechanism is already automatically employed for you e.g. in the deserialization of STL containers whose element type has no default constructor.
Upvotes: 1
Reputation: 409196
The error message is pretty clear:
no matching function for call to 'Player::Player()'
You must have a default constructor in your class.
Upvotes: 2