Ich versuche Boost zu verwenden, um ein Objekt in eine Datei zu serialisieren und die gespeicherten Daten aus der Datei in ein anderes Objekt des gleichen Typs einzulesen.
Doch obwohl ich mit -lboost_serialization
in meinem Makefile bin Verknüpfung, ich bin immer noch mit dem folgenden Fehler vorgestellt, wenn ich versuche, mein Projekt zu kompilieren:Boost text_iarchive nicht verknüpfen
src/core/MainApp.o: In function `boost::archive::text_iarchive& boost::archive::detail::interface_iarchive<boost::archive::text_iarchive>::operator>><boost::archive::class_name_type>(boost::archive::class_name_type&)':
MainApp.cpp:(.text._ZN5boost7archive6detail18interface_iarchiveINS0_13text_iarchiveEErsINS0_15class_name_typeEEERS3_RT_[_ZN5boost7archive6detail18interface_iarchiveINS0_13text_iarchiveEErsINS0_15class_name_typeEEERS3_RT_]+0x2f): undefined reference to `boost::archive::text_iarchive_impl<boost::archive::text_iarchive>::load_override(boost::archive::class_name_type&, int)'
ist hier der Header für die Klasse versuche ich zu serialisiert :
#ifndef RECORD_H_INC
#define RECORD_H_INC
//forward declaration of boost::serialization::access
namespace boost {
namespace serialization {
class access;
}
}
//includes
#include <boost/archive/text_oarchive.hpp>
#include <boost/archive/text_iarchive.hpp>
//Record class declaration
class Record
{
//public fields and methods
public:
//constructor
Record(); //initializes all fields to 0
//destructor
virtual ~Record();
//copy constructor
Record(const Record& r);
//assignment operator
Record& operator=(const Record& src);
//getter methods
int successes() const; //returns the success count
int failures() const; //returns the failure count
int attempts() const; //returns the total number of attempts made
double successPercentage() const; //returns the successes divided by the attempts times 100
//increment methods
void incrementSuccesses(); //increments the success count
void incrementFailures(); //increments the failure count
//protected fields and methods
protected:
int _successes; //the success count
int _failures; //the failure count
int _attempts; //the total attempt count
//make boost friendly
friend class boost::serialization::access;
//template method for serializing the class
template<typename Archive>
void serialize(Archive& ar, const unsigned version) {
ar & _successes & _failures & _attempts; //save the data to disk
}
};
#endif
Hier ist der Header für die MainApp
Klasse:
#ifndef MAIN_APP_H
#define MAIN_APP_H
//includes
#include "../util/funcs.h"
#include "../record/Record.h"
#include <cstdlib>
#include <ctime>
#include <iostream>
#include <string>
#include <fstream>
//class declaration
class MainApp {
//public fields and methods
public:
//constructor
MainApp();
//destructor
virtual ~MainApp();
//copy constructor
MainApp(const MainApp& ma);
//assignment operator
MainApp& operator=(const MainApp& src);
//methods
void run(); //runs the application
//protected fields and methods
protected:
Record* record; //the record storing the training data
std::string recordName; //the path to the file holding the record data
};
#endif
Hier wird die Implementierung für die MainApp
Klasse:
//include header
#include "MainApp.h"
//constructor
MainApp::MainApp()
: record(nullptr), recordName(" ") //init the fields
{
std::srand(std::time(NULL)); //seed the RNG
record = new Record(); //allocate a new Record object
//next we display a prompt
std::cout << "Enter the name of a training record to open." << std::endl;
std::cout << "If the specified record does not exist, it will be created." << std::endl;
std::cout << "Spaces and file extensions are not permitted in this entry." << std::endl;
std::cin >> recordName; //read in the record name
std::cout << "Welcome, " << recordName << "!" << std::endl;
recordName.append(".pre"); //add an extension
if(fileExistsAtPath(recordName)) { //if the record name actually represents a file
std::ifstream load(recordName); //get a stream object for deserialization
boost::archive::text_iarchive ar(load); //get an archive object for deserialization
ar >> record; //and deserialize the record
load.close(); //and close the loading stream
//display the stats
std::cout << "You have made " << record->attempts() << " attempts." << std::endl;
std::cout << "You have " << record->successes() << " successes and "
<< record->failures() << " failures." << std::endl;
std::cout << "You have a " << record->successPercentage() << "%% success rating." << std::endl;
} else {
std::ofstream save(recordName); //get a stream object for serialization
boost::archive::text_oarchive ar(save); //get an archive object for serialization
ar << record; //and serialize the record
save.close(); //and close the saving stream
}
}
//destructor
MainApp::~MainApp() {
if(record != nullptr) { //if the record is not null
delete record; //then delete it
record = nullptr; //and make it null
}
}
//copy constructor
MainApp::MainApp(const MainApp& ma)
: record(nullptr), recordName(ma.recordName) //init the record field to null and copy the recordName field
{
std::srand(std::time(NULL)); //seed the RNG
record = new Record(*ma.record); //copy the other Record object
//welcome the user
std::cout << "Welcome, " << recordName << "!" << std::endl;
//display the stats
std::cout << "You have made " << record->attempts() << " attempts." << std::endl;
std::cout << "You have " << record->successes() << " successes and "
<< record->failures() << " failures." << std::endl;
std::cout << "You have a " << record->successPercentage() << "%% success rating." << std::endl;
}
//assignment operator
MainApp& MainApp::operator=(const MainApp& src) {
*record = *src.record; //assign the record field
recordName = src.recordName; //assign the record name field
return *this; //return the object
}
//run method - runs the application
void MainApp::run() {
std::ofstream save(recordName); //used for saving data
boost::archive::text_oarchive ar(save); //used for saving data
bool shouldQuit = false; //checks whether or not the player should quit
while(!shouldQuit) { //loop while the player isn't quitting
int random = rand() % 37; //0 - 36
int predict = -1; //the player's prediction
std::cout << "Enter your prediction: "; //prompt for a prediction
std::cin >> predict; //read in the prediction
std::cout << std::endl; //newline
if(random == predict) { //if the answers match
std::cout << "Correct!" << std::endl; //then display a message
std::cout << "Your Prediction: " << predict << std::endl;
std::cout << "Correct Answer: " << random << std::endl;
record->incrementSuccesses(); //then increment the record's success count
} else { //if they don't
std::cout << "Too Bad!" << std::endl; //then display a message
std::cout << "Your Prediction: " << predict << std::endl;
std::cout << "Correct Answer: " << random << std::endl;
record->incrementFailures(); //then increment the record's failure count
}
//display stats
std::cout << "You have made " << record->attempts() << " attempts." << std::endl;
std::cout << "You have " << record->successes() << " successes and "
<< record->failures() << " failures." << std::endl;
std::cout << "You have a " << record->successPercentage() << "%% success rating." << std::endl;
ar << record; //serialize the record
char resp = 'y'; //the response of the player as to whether or not to quit
std::cout << "Continue? (y/n)" << std::endl; //prompt for continuing
std::cin >> resp; //read into the response
shouldQuit = (resp == 'y' ? false : true); //get the new shouldQuit value
}
save.close(); //close the save stream
}
//end of implementation
Schließlich ist hier mein Makefile:
CC=g++
CFLAGS=-c -Wall -Wno-unused-value -std=c++14
LIBFLAGS=-lboost_serialization
MAIN=$(shell ls src/*.cpp)
RECR=$(shell ls src/record/*.cpp)
CORE=$(shell ls src/core/*.cpp)
SOURCES=$(MAIN) $(RECR) $(CORE)
OBJECTS=$(SOURCES:.cpp=.o)
EXECUTABLE=Trainer
all: $(SOURCES) $(EXECUTABLE)
$(EXECUTABLE): $(OBJECTS)
$(CC) $(OBJECTS) -o $(EXECUTABLE) $(LIBFLAGS)
mkdir obj
mkdir bin
mv -f $(EXECUTABLE) bin/
mv -f $(OBJECTS) obj/
.cpp.o:
$(CC) $(CFLAGS) $< -o [email protected]
clean:
rm -rf bin
rm -rf obj
Versuchen Sie, '-lboost_system' auch in Ihre Make-Datei einzufügen. – Shravan40
@ Shravan40 Funktioniert immer noch nicht – Techgineer