2017-01-26 2 views
0

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 
+0

Versuchen Sie, '-lboost_system' auch in Ihre Make-Datei einzufügen. – Shravan40

+0

@ Shravan40 Funktioniert immer noch nicht – Techgineer

Antwort

0

Haben Sie versucht, das Hinzufügen:

#include <boost/archive/impl/basic_text_iarchive.ipp> 
#include <boost/archive/impl/text_iarchive_impl.ipp> 
#include <boost/archive/impl/basic_text_oarchive.ipp> 
#include <boost/archive/impl/text_oarchive_impl.ipp> 

ich auch die Vorlage würde versuchen, instanziiert wird, aber es sollte nicht benötigt werden

template class boost::archive::text_oarchive_impl<boost::archive::text_oarchive>; 
template class boost::archive::text_iarchive_impl<boost::archive::text_iarchive>; 
Verwandte Themen