C++ 将带有指向另一个对象的指针的对象写入ASCII文件(C+;+;)
我正在制作一个跟踪不同员工的程序。一些雇员有伴侣(妻子和丈夫),因此所有雇员对象都有一个名为“Partner*Partner”的数据成员(指向伴侣对象的指针) 当我想将员工写入文件时,我的问题就出现了。我可以成功地将所有员工数据(姓名、地址、出生日期等)写入文件,但我不知道如何将合作伙伴写入文件。我在Partner类中有一个名为“writeToFile”的函数,它输出所有Partner数据,但我不知道如何将其“连接”到正确的Employee对象。我试图将“partner”-对象输出到文件的末尾,但这只是增加了一堆零 我应该使用两个单独的文件(一个用于员工,一个用于合作伙伴),还是应该将合作伙伴数据附加到员工数据?当读回文件时,这不会弄乱文件结构吗,因为只有一些员工有合作伙伴,而一些合作伙伴对象只是指向NULL 我的类彼此继承,因此Partner和Employee类都继承成人类,成人类又继承Person类 有人能给我一个“指针”吗?写一个里面有指向另一个对象的指针的对象的最好方法是什么?这是我的临时代码,顺便说一句,如果有兴趣的话:C++ 将带有指向另一个对象的指针的对象写入ASCII文件(C+;+;),c++,pointers,output,fstream,C++,Pointers,Output,Fstream,我正在制作一个跟踪不同员工的程序。一些雇员有伴侣(妻子和丈夫),因此所有雇员对象都有一个名为“Partner*Partner”的数据成员(指向伴侣对象的指针) 当我想将员工写入文件时,我的问题就出现了。我可以成功地将所有员工数据(姓名、地址、出生日期等)写入文件,但我不知道如何将合作伙伴写入文件。我在Partner类中有一个名为“writeToFile”的函数,它输出所有Partner数据,但我不知道如何将其“连接”到正确的Employee对象。我试图将“partner”-对象输出到文件的末尾,
#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。当你释放分配给合作伙伴的内存时dname
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 …