多态——基类指针动态绑定子类对象进行文件输入输出的问题
我写了一个people基类,派生了Student和Friend类,用基类指针指向子类,动态绑定之后,将子类对象的信息,用fstream的write()往txt文件中输出,并提供修改功能。但我发现如果修改覆盖的次数不是很多的时候,用基类指针进行文件read()读取的时候,基类指针还是可以读取后判断是哪种子类实现动态绑定的,获取储存在txt文件中的子类对象的,可是但修改覆盖的次数过多时,基类指针不能判断是哪种子类了,导致不能动态绑定,基类指针指向的对象调试的是基类的,但调用了子类的特殊函数,最后报错。
为什么读写次数多了……会这样呢?
//主函数
int main()
{
fstream inout("Family.txt",ios::in|ios::out);
Student a("name","birthday","phone","email");
Friend b("name2","birthday2","phone2","email2");
int kind;
people* ptr=NULL;
while(cin>>kind)
{
switch(kind)
{
case 1:ptr=&a;
cout<<"School name:";
break;
case 2:ptr=&b;
cout<<"Meet place:";
break;
}
char special[20];
cin>>special;
ptr->set(special);
inout.write(reinterpret_cast<char*>(ptr),sizeof(Student));
}
inout.seekg(0,ios::end);
long posend = inout.tellp();
inout.seekg(0);
for(int i=0;posend!= inout.tellp() ;i++)
{
inout.seekg(i*sizeof(Student));
inout.read(reinterpret_cast<char*>(ptr),sizeof(Student));
cout<<left<<setw(15)<<ptr->getname()<<left<<setw(15)<<ptr->getbirthday()<<left<<setw(15)
<<ptr->getphone()<<left<<setw(15)<<ptr->getemail()<<left<<setw(15)<<ptr->getspecial()<<endl;
}
inout.close();
return 0;
}
//基类:
class people
{
public:
people(string n="",string b="",string p="",string e="");
void setname(string);
string getname() const;
void setbirthday(string);
string getbirthday() const;
void setphone(string);
string getphone() const;
void setemail(string);
string getemail() const;
virtual void set(string){}
virtual string getspecial() { return (string)"";}
private:
char name[20];
char birthday[20];
char phone[20];
char email[20];
char special[20];
};
//子类
class Student : public people
{
public:
Student(string n="",string b="",string p="",string e="",string s="")
:people(n,b,p,e)
{
set(s);
}
void set(string specialstring)
{
const char* SchoolName=specialstring.data();
int length=specialstring.size();
length=(length<15?length:14);
strncpy(schoolname,SchoolName,length);
schoolname[length]='\0';
}
string getspecial()
{
return schoolname;
}
private:
char schoolname[20];
};
class Friend : public people
{
public:
Friend (string n="",string b="",string p="",string e="",string s="")
:people(n,b,p,e)
{
set(s);
}
void set(string specialstring)
{
const char* Friend_Meet=specialstring.data();
int length=specialstring.size();
length=(length<15?length:14);
strncpy(friend_Meet,Friend_Meet,length);
friend_Meet[length]='\0';
}
string getspecial()
{
return friend_Meet;
}
private:
char friend_Meet[20];
};
[解决办法]
people中的数据成员设成private也是可以的,只要提供足够多的接口函数,子类通过接口函数可以访问数据成员。
你的问题出在:
int main(){fstream inout("Family.txt",ios::in|ios::out);Student a("name","birthday","phone","email");Friend b("name2","birthday2","phone2","email2");int kind;people* ptr=NULL;while(cin>>kind){switch(kind){case 1:ptr=&a;cout<<"School name:";break;case 2:ptr=&b;cout<<"Meet place:";break;}char special[20];cin>>special;ptr->set(special); inout.write(reinterpret_cast<char*>(ptr),sizeof(Student)); //这里ptr如果指向Friend b,sizeof(Student)长度就不对。。。}