调用 class 的成员函数后的垃圾值
garbage value after calling a member function of a class
我试图从 class b 调用 class a 的成员,但没有成功它工作但总是为 class a 中的向量提供垃圾值,是的,例外第三次被抛出,而读取循环只应该 运行 两次。
b.h
#pragma once
#include <iostream>
#include <fstream>
#include <vector>
#include <string>
#include <iomanip>
#include "a.h"
using namespace std;
class b {
fstream fio;
string s;
a aio;
public:
b(string);
b( b& );
void all(string);
void out();
void reset();
~b();
};
b.cpp
#include "b.h"
b::b(string in)
:fio{ "see.bin",ios::in | ios::out | ios::binary | ios::app }, s{ in }
{
}
b::b( b& bi )
: fio{ "see.bin",ios::in | ios::out | ios::binary | ios::app }, s{ bi.s }
{
}
void b::all(string in) {
s = in;
reset();
aio.set_n( s ); //n is a string in a class
aio.set_s( 11 ); // s is a size_t object in a class
aio.set_v( 114 ); // v is the vector in a class
fio.write( ( char* )&aio, sizeof( aio ) );
reset();
}
void b::out() {
reset();
while (fio.read( ( char* )&aio, sizeof( aio ) //read function gone rouge
aio.print();
}
void b::reset() {
fio.clear();
fio.seekg( 0, ios_base::beg );
}
b::~b() {
fio.close();
}
main.cpp
#include "b.h"
int main() {
b obj_1( "" );
obj_1.all( "xyz" );
obj_1.out();
}
a.cpp
#include "a.h"
a::a()
:s{ 0 }
{
}
a::a( a& ai )
: s{ ai.s }, n{ ai.n }
{
for (auto c : ai.v)
v.push_back( c );
}
a::a( a&& ai ) noexcept
:s{ ai.s }, n{ ai.n }
{
for (auto c : ai.v)
v.push_back( c );
ai.v.clear();
}
void a::set_v( int i ) {v.push_back( i );}
void a::set_s( size_t si ) { s = si;}
void a::set_n( string na ) {n = na;}
void a::print(){
cout << s << " " << n << " ";
for (int &p : v)
cout << " " << p;
}
a::~a() {v.clear();}
作为参考,a 是一个 class 具有复制构造函数、移动构造函数、普通构造函数、每个对象的所有 setter 和析构函数。
感谢您帮助我并阅读我写得不好的代码。
非POD类型不能直接写入或读取。例如,std::string class。字符串 class 有一些成员数据,但通常,字符串内容在其他地方(比如在动态内存中)。
我建议为您的 class 定义 <<
和 >>
运算符以序列化和反序列化。
Boost::serialization
library handles this rather elegantly. I've used it in several projects. There's an example program, showing how to use it, here.
唯一的本机方法是使用流。这基本上就是 Boost::serialization
库所做的全部,它通过设置一个框架来扩展流方法,以将对象写入类似文本的格式并从相同的格式读取它们。
对于内置类型,或者您自己的类型 operator<<
和 operator>>
正确定义,这很简单;有关详细信息,请参阅 the C++ FAQ。
另见 Qt serialization and protobuf
**编辑:**
试试这个,但这不是便携式的,它不能处理所有的极端情况。
#include <iostream>
#include <string>
#include <vector>
#include <fstream>
class Bin {
public:
void set_size(size_t s) { size_ = s; }
void set_str(const std::string& s) { str_ = s; }
void append_int(int s) { vec_.emplace_back(s); }
public:
size_t get_size(void) const { return size_; }
std::string get_str(void) const { return str_; }
std::vector<int> get_vec(void) const { return vec_; }
public:
void print(void) const
{
std::cout << "---- A ----" << std::endl;
std::cout << "Size: " << size_ << std::endl;
std::cout << "Str: " << str_ << std::endl;
std::cout << "Vec: ";
for (const auto& i: vec_)
std::cout << i << " ";
std::cout << std::endl;
std::cout << "-----------" << std::endl;
}
public:
friend std::ofstream& operator<<(std::ofstream& fstream, const Bin& obj)
{
size_t str_size = obj.str_.length();
size_t vec_size = obj.vec_.size();
fstream.write(reinterpret_cast<const char *>(&obj.size_), sizeof(obj.size_));
fstream.write(reinterpret_cast<const char *>(&str_size), sizeof(str_size));
for (const auto& i: obj.str_)
fstream.write(reinterpret_cast<const char *>(&i), sizeof(i));
fstream.write(reinterpret_cast<const char *>(&vec_size), sizeof(vec_size));
for (const auto& i: obj.vec_)
fstream.write(reinterpret_cast<const char *>(&i), sizeof(i));
return fstream;
}
public:
friend std::ifstream& operator>>(std::ifstream& fstream, Bin& obj)
{
obj.str_.clear();
obj.vec_.clear();
size_t size = 0;
fstream.read(reinterpret_cast<char *>(&obj.size_), sizeof(obj.size_));
fstream.read(reinterpret_cast<char *>(&size), sizeof(size));
for (size_t i = 0; i < size; i++)
{
char c;
fstream.read(&c, sizeof(c));
obj.str_.push_back(c);
}
fstream.read(reinterpret_cast<char *>(&size), sizeof(size));
for (size_t i = 0; i < size; i++)
{
int j;
fstream.read(reinterpret_cast<char *>(&j), sizeof(j));
obj.vec_.emplace_back(j);
}
return fstream;
}
private:
size_t size_;
std::string str_;
std::vector<int> vec_;
};
int main(void)
{
Bin a, b;
a.set_size(100);
a.set_str("Whosebug");
for (int i = 0; i < 10; i++)
a.append_int(i + 1);
a.print();
{
std::ofstream ostream("see.bin", std::ios::out | std::ios::binary);
ostream << a;
}
std::ifstream istream("see.bin", std::ios::in | std::ios::binary);
istream >> b;
b.print();
return 0;
}
我试图从 class b 调用 class a 的成员,但没有成功它工作但总是为 class a 中的向量提供垃圾值,是的,例外第三次被抛出,而读取循环只应该 运行 两次。
b.h
#pragma once
#include <iostream>
#include <fstream>
#include <vector>
#include <string>
#include <iomanip>
#include "a.h"
using namespace std;
class b {
fstream fio;
string s;
a aio;
public:
b(string);
b( b& );
void all(string);
void out();
void reset();
~b();
};
b.cpp
#include "b.h"
b::b(string in)
:fio{ "see.bin",ios::in | ios::out | ios::binary | ios::app }, s{ in }
{
}
b::b( b& bi )
: fio{ "see.bin",ios::in | ios::out | ios::binary | ios::app }, s{ bi.s }
{
}
void b::all(string in) {
s = in;
reset();
aio.set_n( s ); //n is a string in a class
aio.set_s( 11 ); // s is a size_t object in a class
aio.set_v( 114 ); // v is the vector in a class
fio.write( ( char* )&aio, sizeof( aio ) );
reset();
}
void b::out() {
reset();
while (fio.read( ( char* )&aio, sizeof( aio ) //read function gone rouge
aio.print();
}
void b::reset() {
fio.clear();
fio.seekg( 0, ios_base::beg );
}
b::~b() {
fio.close();
}
main.cpp
#include "b.h"
int main() {
b obj_1( "" );
obj_1.all( "xyz" );
obj_1.out();
}
a.cpp
#include "a.h"
a::a()
:s{ 0 }
{
}
a::a( a& ai )
: s{ ai.s }, n{ ai.n }
{
for (auto c : ai.v)
v.push_back( c );
}
a::a( a&& ai ) noexcept
:s{ ai.s }, n{ ai.n }
{
for (auto c : ai.v)
v.push_back( c );
ai.v.clear();
}
void a::set_v( int i ) {v.push_back( i );}
void a::set_s( size_t si ) { s = si;}
void a::set_n( string na ) {n = na;}
void a::print(){
cout << s << " " << n << " ";
for (int &p : v)
cout << " " << p;
}
a::~a() {v.clear();}
作为参考,a 是一个 class 具有复制构造函数、移动构造函数、普通构造函数、每个对象的所有 setter 和析构函数。 感谢您帮助我并阅读我写得不好的代码。
非POD类型不能直接写入或读取。例如,std::string class。字符串 class 有一些成员数据,但通常,字符串内容在其他地方(比如在动态内存中)。
我建议为您的 class 定义 <<
和 >>
运算符以序列化和反序列化。
Boost::serialization
library handles this rather elegantly. I've used it in several projects. There's an example program, showing how to use it, here.
唯一的本机方法是使用流。这基本上就是 Boost::serialization
库所做的全部,它通过设置一个框架来扩展流方法,以将对象写入类似文本的格式并从相同的格式读取它们。
对于内置类型,或者您自己的类型 operator<<
和 operator>>
正确定义,这很简单;有关详细信息,请参阅 the C++ FAQ。
另见 Qt serialization and protobuf
**编辑:**
试试这个,但这不是便携式的,它不能处理所有的极端情况。
#include <iostream>
#include <string>
#include <vector>
#include <fstream>
class Bin {
public:
void set_size(size_t s) { size_ = s; }
void set_str(const std::string& s) { str_ = s; }
void append_int(int s) { vec_.emplace_back(s); }
public:
size_t get_size(void) const { return size_; }
std::string get_str(void) const { return str_; }
std::vector<int> get_vec(void) const { return vec_; }
public:
void print(void) const
{
std::cout << "---- A ----" << std::endl;
std::cout << "Size: " << size_ << std::endl;
std::cout << "Str: " << str_ << std::endl;
std::cout << "Vec: ";
for (const auto& i: vec_)
std::cout << i << " ";
std::cout << std::endl;
std::cout << "-----------" << std::endl;
}
public:
friend std::ofstream& operator<<(std::ofstream& fstream, const Bin& obj)
{
size_t str_size = obj.str_.length();
size_t vec_size = obj.vec_.size();
fstream.write(reinterpret_cast<const char *>(&obj.size_), sizeof(obj.size_));
fstream.write(reinterpret_cast<const char *>(&str_size), sizeof(str_size));
for (const auto& i: obj.str_)
fstream.write(reinterpret_cast<const char *>(&i), sizeof(i));
fstream.write(reinterpret_cast<const char *>(&vec_size), sizeof(vec_size));
for (const auto& i: obj.vec_)
fstream.write(reinterpret_cast<const char *>(&i), sizeof(i));
return fstream;
}
public:
friend std::ifstream& operator>>(std::ifstream& fstream, Bin& obj)
{
obj.str_.clear();
obj.vec_.clear();
size_t size = 0;
fstream.read(reinterpret_cast<char *>(&obj.size_), sizeof(obj.size_));
fstream.read(reinterpret_cast<char *>(&size), sizeof(size));
for (size_t i = 0; i < size; i++)
{
char c;
fstream.read(&c, sizeof(c));
obj.str_.push_back(c);
}
fstream.read(reinterpret_cast<char *>(&size), sizeof(size));
for (size_t i = 0; i < size; i++)
{
int j;
fstream.read(reinterpret_cast<char *>(&j), sizeof(j));
obj.vec_.emplace_back(j);
}
return fstream;
}
private:
size_t size_;
std::string str_;
std::vector<int> vec_;
};
int main(void)
{
Bin a, b;
a.set_size(100);
a.set_str("Whosebug");
for (int i = 0; i < 10; i++)
a.append_int(i + 1);
a.print();
{
std::ofstream ostream("see.bin", std::ios::out | std::ios::binary);
ostream << a;
}
std::ifstream istream("see.bin", std::ios::in | std::ios::binary);
istream >> b;
b.print();
return 0;
}