C++ 将带有指向另一个对象的指针的对象写入ASCII文件(C+;+;)

C++ 将带有指向另一个对象的指针的对象写入ASCII文件(C+;+;),c++,pointers,output,fstream,C++,Pointers,Output,Fstream,我正在制作一个跟踪不同员工的程序。一些雇员有伴侣(妻子和丈夫),因此所有雇员对象都有一个名为“Partner*Partner”的数据成员(指向伴侣对象的指针) 当我想将员工写入文件时,我的问题就出现了。我可以成功地将所有员工数据(姓名、地址、出生日期等)写入文件,但我不知道如何将合作伙伴写入文件。我在Partner类中有一个名为“writeToFile”的函数,它输出所有Partner数据,但我不知道如何将其“连接”到正确的Employee对象。我试图将“partner”-对象输出到文件的末尾,

我正在制作一个跟踪不同员工的程序。一些雇员有伴侣(妻子和丈夫),因此所有雇员对象都有一个名为“Partner*Partner”的数据成员(指向伴侣对象的指针)

当我想将员工写入文件时,我的问题就出现了。我可以成功地将所有员工数据(姓名、地址、出生日期等)写入文件,但我不知道如何将合作伙伴写入文件。我在Partner类中有一个名为“writeToFile”的函数,它输出所有Partner数据,但我不知道如何将其“连接”到正确的Employee对象。我试图将“partner”-对象输出到文件的末尾,但这只是增加了一堆零

我应该使用两个单独的文件(一个用于员工,一个用于合作伙伴),还是应该将合作伙伴数据附加到员工数据?当读回文件时,这不会弄乱文件结构吗,因为只有一些员工有合作伙伴,而一些合作伙伴对象只是指向NULL

我的类彼此继承,因此Partner和Employee类都继承成人类,成人类又继承Person类

有人能给我一个“指针”吗?写一个里面有指向另一个对象的指针的对象的最好方法是什么?这是我的临时代码,顺便说一句,如果有兴趣的话:

#include  <iostream>
#include  <fstream>
#include  <cstring>
#include  <cctype> 
#include  <cstdlib>
using namespace std;

const int MAXTXT = 80;

class Person {     
    protected:
        char* firstname;   
        char  birthdate[6]; 
    public:
        Person() {
            char fname[MAXTXT];
            cout << "First name: "; cin.getline(fname, MAXTXT);
            firstname = new char[strlen(fname + 1)];
            strcpy(firstname, fname);
            cout << "Birth date (DDMMYY): ";
            cin >> birthdate; cin.ignore();
            }
        void display() {
            cout << "\nFirst name: " << firstname;
            cout << "\nBorn: " << birthdate;
            }
        void writeToFile(ofstream & ut) {
            ut << firstname << "\n" << birthdate;
            }
        };

class Adult: public Person {
    protected:
        char* lastname;
    public:
        Adult() {
            char lname[MAXTXT];
            cout << "Last name: "; cin.getline(lname, MAXTXT);
            lastname = new char[strlen(lname + 1)];
            strcpy(lastname, lname);
            }
        void writeToFile(ofstream & out) {
            out << "\n" << lastname << "\n";
            }
        void display() {
            cout << "\nLast name: " << lastname;
            }
        };

class Partner: public Adult {
    private:
        int phone1;
        int phone2;
    public:
        Partner() {
            cout << "Phone (mobile): "; cin >> phone1;
            cout << "\nPhone (job): ";  cin >> phone2; cin.ignore();
            }
        void writeToFile(ofstream & out) {
            Person::writeToFile(out);
            Adult::writeToFile(out);
            out << "\n" << phone1 << " " << phone2;
            }
        void display() {
            Person::display();
            Adult::display();
            cout << "\nPhone (mobile): " << phone1;
            cout << "\nPhone (job): " << phone2;
            }
        };

class Employee: public Adult {      
    private:
        int      nr;                    
        char*    address;               
        Partner* partner;               
    public:
        Employee() {
            }
        Employee(int n) {
            char adr[MAXTXT];
            nr = n;
            cout << "Address: "; cin.getline(adr, MAXTXT);
            address = new char[strlen(adr + 1)];
            strcpy(address, adr);
            partner = NULL;
            }
        void changePartner() {
            Partner::Partner();
            }
        void writeToFile(ofstream & out) {
            Person::writeToFile(out);
            Adult::writeToFile(out);
            out << nr << "\n" << address << endl;
            }
        void display() {
            Person::display();
            Adult::display();
            cout << "\nAddress: " << address;
            if(partner) {
                partner->display();
                }
            }
        int returnEmpNr() {
            return nr;
            }
        };

Employee* employees[100];
int lastUsed = 0;

int main() {

    }

void writeToFile() {
    ofstream outfile("EMPLOYEES.DAT");
    ofstream outfile2("PARTNERS.DAT");
    outfile << lastUsed << "\n";
    for(int i = 1; i <= lastUsed; i++) {
        employees[i]->writeToFile(outfile);
        }
#包括
#包括
#包括
#包括
#包括
使用名称空间std;
常量int MAXTXT=80;
类人{
受保护的:
char*名字;
出生日期[6];
公众:
人(){
字符fname[MAXTXT];
cout生日;cin.ignore();
}
无效显示(){

cout指针除了指向程序的一次运行之外没有任何意义,如果指针的值为,则在读取文件时很可能毫无意义。同一个
伙伴
位于内存中同一位置的几率,假设已经为其分配了空间,下一次可能与18446744073709551中的1一样糟糕,616和出错通常会产生致命的结果。这些致命的结果意味着你很幸运。你可以粉碎属于其他东西的完全有效的内存,并导致奇怪的、未定义的行为,并且比彻底崩溃更难调试

在C++指针中,P>通常是一个傻瓜式的选择。把它们作为最后的手段,因为它们可以真正增加你需要编写的代码量。 (但不一定是两个文件。两个列表可以很容易地存在于一个文件中)一个是
合作伙伴
s,另一个是
员工
s。
合作伙伴
s似乎不需要了解员工
s,所以省去一些麻烦,先在合作伙伴列表中写出并阅读

在编写
员工
列表时,不要存储
合作伙伴
指针,因为它不起作用。而是将
合作伙伴
的索引存储在
合作伙伴
列表中。然后,当您读取
员工
列表时,您可以读取
合作伙伴
表中的
合作伙伴
位置,并查找该位置
合作伙伴
,并指向他们。这就是为什么首先编写和读取
合作伙伴
要容易得多的原因;很难在尚未读取的列表中查找数据

或者完全抛弃
合作伙伴
指针的概念,始终使用索引查找
合作伙伴
。这是一种更安全的方法,只要您始终将新合作伙伴添加到列表中,并且永远不要插入列表或执行类似于洗牌列表之类的愚蠢操作

当我们在处理指针时,请仔细阅读“”,因为您正陷入内存管理大屠杀的泥潭

正如每次你复制一名
员工时所写的那样,你会得到另一名被愚蠢地复制的
员工
。它复制的是指针,而不是内容,因此你现在有两个
员工
对象指向相同的
名称
合作伙伴
s。当你释放分配给
合作伙伴
的内存时d
name
s,另一个副本指向您的程序不再拥有的内存,并成为一颗滴答作响的定时炸弹,等待程序崩溃

使用
std::vector
(注意它是
Partner
vector
,而不是
Partner*
。这允许
vector
拥有和管理您的所有内存,而不仅仅是列表所需的内存)索引清除了
Partner
s的问题,因为
std::vector
为您管理内存,但名称仍在等待终止程序。将
char*
s替换为
std::string
也可以解决该问题,方法是将内存管理负担从代码转移到
std::string
它是在20世纪90年代为您编写的,从那时起已经在数百万个程序中使用。20年后留下来的bug不多

如果你必须使用指针和指针数组,你需要定制析构函数、复制构造函数、移动构造函数、赋值操作符和移动操作符。这是一项额外的工作


但是那些
vector
s和
string
s包含指针,你必须小心地编写它们。这个主题,序列化,已经在其他地方被击败了。

你必须使你的类可以序列化。OT:为什么你避免
std::string
作为名称,而不使用某种
std:SypDyPosiths//Cudio/<代码>:STD::UNIQUYGPTR <代码>合作伙伴。您可以将ID成员(INTION)添加到人类(数据库类…)。您也假设(一夫一妻制除外),合作伙伴也不能成为雇员。BTW,考虑使用<代码> STD:向量< /代码>,<代码> STD::MAP,<代码> STD::String …