我正在研究boost序列化,并且编写了以下代码,该序列化了B
类的对象,而该序列又序列化了A
类的对象。
当我尝试将代码拆分为多个文件,分别将两个类的声明和实现分开时,出现以下链接器错误。
make -k
g++ -std=c++11 main.cpp a.cpp b.cpp -lboost_serialization -lboost_filesystem -lboost_system
Undefined symbols for architecture x86_64:
"void B::serialize<boost::archive::binary_iarchive>(boost::archive::binary_iarchive&, unsigned int)", referenced from:
void boost::serialization::access::serialize<boost::archive::binary_iarchive, B>(boost::archive::binary_iarchive&, B&, unsigned int) in main-5e4da5.o
"void B::serialize<boost::archive::binary_oarchive>(boost::archive::binary_oarchive&, unsigned int)", referenced from:
void boost::serialization::access::serialize<boost::archive::binary_oarchive, B>(boost::archive::binary_oarchive&, B&, unsigned int) in main-5e4da5.o
ld: symbol(s) not found for architecture x86_64
clang: error: linker command failed with exit code 1 (use -v to see invocation)
make: *** [build] Error 1
我设法通过添加一些额外的代码来解决链接器错误,但是在程序打印“保存”之后,我又遇到了段错误。 怎么了?
有效的代码,1个文件
main.cpp
// g++ -std=c++11 main.cpp a.cpp b.cpp -lboost_serialization -lboost_filesystem -lboost_system
#include <iostream>
#include <fstream>
#include <boost/archive/binary_iarchive.hpp>
#include <boost/archive/binary_oarchive.hpp>
#include <boost/filesystem.hpp>
class A {
public:
int num;
template<class Archive>
void serialize(Archive & ar, unsigned int version)
{
ar & num;
}
};
class B {
public:
A a;
template<class Archive>
void serialize(Archive & ar, unsigned int version)
{
ar & a;
}
};
int main(int argc, char * argv[]) {
B b;
if(!boost::filesystem::exists("saved")) {
b.a.num = 15;
std::ofstream out("saved");
boost::archive::binary_oarchive oa(out);
oa << b;
out.close();
} else {
std::ifstream in("saved");
boost::archive::binary_iarchive ia(in);
ia >> b;
in.close();
}
std::cout << b.a.num << "\n";
return 0;
}
无效的代码,最多5个文件
main.cpp
// g++ -std=c++11 main.cpp a.cpp b.cpp -lboost_serialization -lboost_filesystem -lboost_system
#include <iostream>
#include <fstream>
#include <boost/archive/binary_iarchive.hpp>
#include <boost/archive/binary_oarchive.hpp>
#include <boost/filesystem.hpp>
#include "b.hpp"
int main(int argc, char * argv[]) {
B b;
if(!boost::filesystem::exists("saved")) {
b.a.num = 15;
std::cout << "saving\n";
std::ofstream out("saved", std::ios::binary);
boost::archive::binary_oarchive oa(out);
oa << b;
out.close();
std::cout << "saved\n";
} else {
std::cout << "loading\n";
std::ifstream in("saved", std::ios::binary);
boost::archive::binary_iarchive ia(in);
ia >> b;
in.close();
std::cout << "loaded\n";
}
std::cout << b.a.num << "\n";
return 0;
}
b.hpp
#ifndef B_H
#define B_H
#include "a.hpp"
class B {
public:
A a;
template<class Archive>
void serialize(Archive & ar, unsigned int version);
};
/*
// without the following code I get a linking error, but anyway, the code leads to a crash
namespace boost
{
namespace serialization
{
template<class Archive>
void serialize(Archive & ar, B & b, unsigned int version)
{
ar & b;
}
}
}
*/
#endif // B_H
b.cpp
#include "b.hpp"
#include <boost/archive/binary_iarchive.hpp>
#include <boost/archive/binary_oarchive.hpp>
template<class Archive>
void B::serialize(Archive & ar, unsigned int version)
{
ar & a;
}
a.hpp
#ifndef A_H
#define A_H
class A {
public:
int num;
template<class Archive>
void serialize(Archive & ar, unsigned int version);
};
#endif // A_H
a.cpp
#include "a.hpp"
#include <boost/archive/binary_iarchive.hpp>
#include <boost/archive/binary_oarchive.hpp>
template<class Archive>
void A::serialize(Archive & ar, unsigned int version)
{
ar & num;
}