调用 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;
}