我正在制作一个跟踪不同员工的计划。一些员工有合作伙伴(妻子和丈夫),因此所有员工对象都有一个名为"合作伙伴*合作伙伴" (指向Partner对象的指针)。
当我想将一个Employee写入文件时,我的问题出现了。我可以成功地将所有员工数据(姓名,地址,出生日期等)写入文件,但我不知道如何将合作伙伴写入文件。我在Partner类中有一个名为" writeToFile"的函数。输出所有合作伙伴数据,但我不知道如何连接"它到正确的Employee对象。我试图将" partner" -object输出到文件的末尾,但这只是添加了一堆零。
我应该使用两个单独的文件(一个用于员工,一个用于合作伙伴),还是应该将合作伙伴数据附加到员工数据?读回来时不会弄乱文件结构,因为只有部分员工有合作伙伴而某些合作伙伴对象只指向NULL?
我的类相互继承,因此Partner和Employee类都继承了Adult类,后者再次继承了Person类。
任何人都可以给我一个"指针"编写一个指向其中另一个对象的指针的最佳方法是什么?这是我的临时代码btw,如果有任何兴趣:
#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);
}
答案 0 :(得分:0)
除了程序的单次运行之外,指针是没有意义的,如果指针处于值has gone out of scope,则在读取文件时很可能没有意义。同一Partner
存在于内存中相同位置的几率,假设空间已被分配给它,下一次可能与18,446,744,073,709,551,616中的1一样糟糕,并且错误通常会导致致命的结果。那些致命的结果意味着你很幸运。你可以粉碎属于其他东西的完全有效的内存,并导致行为奇怪,未定义,并且比直接崩溃更难调试。
在C ++中,指针往往是一个糟糕的赌注。使用它们作为最后的手段,因为它们可以真正增加您需要编写的代码量。
I recommend two lists(但不一定是两个文件。两个列表都可以轻松存在于一个文件中)Partner
和Employee
之一。 Partner
似乎不需要了解Employee
,所以请先省去一些麻烦,然后先写下并阅读合作伙伴列表。
在撰写Employee
列表时,请不要存储Partner
指针,因为它无法正常工作。而是将Partner
的索引存储在Partner
列表中。然后,当您阅读Employee
列表时,您可以在Partner
表格中查看Partner
的位置,查看Partner
,并指向它们。这就是为什么首先编写和阅读Partner
更容易的原因;很难在尚未阅读的列表中查找数据。
或完全抛弃Partner
指针的概念,并始终使用索引来查看Partner
。这是一种更安全的方法,只要你总是将新的合作伙伴添加到列表中,并且永远不会插入列表或做一些愚蠢的事情,就像洗牌一样。
虽然我们正在弄乱指针,但请仔细阅读&#34; What is The Rule of Three?&#34;因为你正在陷入记忆管理大屠杀的泥潭。
正如每次复制Employee
时所写的那样,您将获得另一个被愚蠢复制的Employee
。它复制指针而不是内容,因此您现在有2个Employee
个对象指向相同的name
和Partner
s。当你释放分配给partner
和name
,which you don't and really, really should的内存时,另一个副本指向你的程序不再拥有的内存,并成为一个等待崩溃的定时炸弹你的计划。
使用std::vector<Partner>
(请注意它是vector
的{{1}},而非Partner
。这允许Partner *
拥有并管理所有内存对于你而不仅仅是列表所需的内存)和索引清除了vector
的问题,因为Partner
为你管理内存,但名称仍在等待杀死程序。用std::vector
替换char *
将解决这个问题,同样也可以将内存管理负担从代码移到std::string
,在那里它是在20世纪90年代为你编写的,并且已经在从那以后在数百万个程序中使用。 20年后没有多少虫子可以绊倒。
如果必须使用指针和指针数组,则需要创建自定义析构函数,复制构造函数,移动构造函数,赋值运算符和移动运算符。这是一项额外的工作。
但是那些std::string
和vector
包含指针,你必须小心处理它们。这个主题序列化在其他地方被打死了,so here's a link to a reputable site that can probably handle it better than I can。