我需要你的帮助,因为我似乎无法理解SO上和其他网站上关于插入操作符重载的任何(许多)各种解决方案。
我要创建一个“数据库”,由一个单独的向量组成的员工,除其他外,我必须能够保存到文本文件。
代码必须有一个名为Employees的基类和三个名为Manager,Engineer和Researcher的派生类。
基于:
for (vector<Employees*>::iterator i = midzer.begin(); i != midzer.end(); ++i)
{
(*i)->printStats();
}
/* printStats is a virtual method outputting all data contained in the objects to
the console window. It's implemented like so for one of the derived classes:*/
void Manager::printStats()
{
cout << "\nManager." << endl;
cout << "First name: " << mFirstName << endl; // data member of base class
cout << "Last name: " << mLastName << endl; // data member of base class
cout << "Salary: " << mSalary << endl; // data member of base class
cout << "Meetings per week: " << mNumberOfMeetingsPerWeek << endl; // data member of derived class
cout << "Vacation Days per year: " << mNumberOfVacationDaysPerYear << endl; //data member of derived class
cout << endl;
}
我以为我可以像下面那样创建一个ostream对象瞧..
ofstream outfile;
outfile.open("/users/mundt/desktop/EmployeeDatabase.txt");
for (vector<Employees*>::iterator i = midzer.begin(); i != midzer.end(); ++i)
{
outfile << (*i)->printStats();
}
outfile.close();
正如您(可能)知道这是不可能的,我必须为基类Employees重载插入运算符,并使其多态以某种方式能够访问派生类部分。
我正在寻找的是一种使用printStats()方法将矢量中所有对象的数据输出到文本文件的方法。
如果有人可以提供一些示例代码来执行此操作,将非常感谢。谢谢。
答案 0 :(得分:2)
首先,应告知printStats
将数据放在何处,而不是始终将其写入cout
。
void Manager::printStats(std::ostream& out) const //function doesn't modify, so const
{
out << "\nManager." << endl;
out << "First name: " << mFirstName << endl; // data member of base class
out << "Last name: " << mLastName << endl; // data member of base class
out << "Salary: " << mSalary << endl; // data member of base class
out << "Meetings per week: " << mNumberOfMeetingsPerWeek << endl; // data member of derived class
out << "Vacation Days per year: " << mNumberOfVacationDaysPerYear << endl; //data member of derived class
out << endl;
}
然后告诉C ++如何将您的类插入流中:
std::ostream& operator<<(std::ostream& out, const Employees& employee)
{
employee.printStats(out);
return out; //return ostreams by reference when done
}
如果您愿意,可以为矢量添加另一个,这几乎与您的旧循环完全相同
std::ostream& operator<<(std::ostream& out, const vector<Employees*>& midzer)
{
for (vector<Employees*>::const_iterator i = midzer.begin(); i != midzer.end(); ++i)
{
out << *(*i);
}
//or if you have a newer compiler:
//for (Employees* i : midzer) out << *i;
return out; //return ostreams by reference when done
}
最后,输出矢量
ofstream outfile;
outfile.open("/users/mundt/desktop/EmployeeDatabase.txt");
outfile << midzer; //well that's easy
outfile.close();
此处的演示演示:http://coliru.stacked-crooked.com/a/03fd3b4e23dc7ee2
答案 1 :(得分:2)
这样做有很多选择,我将描述3:
operator<<
(与上述2之一结合使用)更多细节:
如果您从printStats()
函数返回一个字符串,那么您可以将其写入ofstream
:
std::string Manager::printStats()
{
std::stringstream ss;
ss << "\nManager." << endl;
ss << "First name: " << mFirstName << endl; // data member of base class
ss << "Last name: " << mLastName << endl; // data member of base class
ss << "Salary: " << mSalary << endl; // data member of base class
ss << "Meetings per week: " << mNumberOfMeetingsPerWeek << endl; // data member of derived class
ss << "Vacation Days per year: " << mNumberOfVacationDaysPerYear << endl; //data member of derived class
ss << endl;
return ss.str();
}
如果您将ostream
传入此功能,则可以直接输出到该功能。 (您可能希望将该函数定义为void printStats( std::ostream& os = std::cout );
,因此如果您在没有参数的情况下调用它,它将默认为cout
:
void Manager::printStats( std::ostream& os )
{
os << "\nManager." << endl;
//...
}
在你的例子中会这样调用:
(*i)->printStats( outFile );
如果您重载operator<<
,则可以直接将其传递给outFile
。
std::ostream& operator<<( std::ostream& os, const Employee& e )
{
os << e.printStats();
// or
e.printStats( os );
// for both cases
return os;
}
然后可以这样称呼:
outFile << *(*i);
答案 2 :(得分:0)
cout
是函数ostream
正在打印的特定PrintStats
。您正在寻找的是为您的类型重载operator<<
。
std::ostream & operator<<(std::ostream & s, const Employee& m)
{
m.Stream(s);
return s;
}
然后这可以用作:
outfile << *i;
然后在virtual Stream() const
中声明一个函数Employee
并在Manager