具体来说,我希望能够在基类的两个派生类中使用ostream
operator <<
。
我正在创建的程序应打印出“虚拟商店”中各种“产品”的产品详细信息。其中有两种不同的书籍。这些书中的每一本都应该是自己的:
ID number
Author
NumberOfPages
Year
此外,类型ChildrensBook
需要保持最低年龄,TextBook
需要保持成绩。
我定义了类Book
,并从类ChildrensBook
和TextBook
派生。我的问题是使用ostream
operator <<
打印出来的信息。
我可以定义泛型&lt;&lt; Book类中的函数,它将打印出两个派生类共有的所有信息,然后在&lt;&lt;的重新定义中引用它。在派生类中?
例如,
//The parent class
ostream& operator<<(ostream& bookOutput, const Book& printBook) {
return bookOutput << printBook.ID << "Name " << printBook.name << "year:" << printBook.year";
}
然后在派生类中以某种方式:
//The derived classes
ostream& operator<<(ostream& TextBookOutput, const TextBook& printTextBook) {
return TextBookOutput << "TextBook: "
<< "[Here is where I want to print out all the details of the book that are members of the base class]" << "Grade:" << printTextBook.grade;
}
所以我想我的问题可以总结为:我可以在子运算符中调用父运算符,如果是,我会使用什么语法?
我想到的另一个想法是为使用父打印操作符的子程序编写一个函数,然后从子程序的print操作符中调用该函数。这意味着我没有尝试在重新定义时调用运算符,但仍然要求使用父运算符并单独重新定义子运算符。
答案 0 :(得分:4)
不确定
您有Book
的运营商,因此请使用它。你可以通过给它一本书的引用来调用它,你可以使用多态的力量来获得一个基础的引用。
ostream& operator<<(ostream& TextBookOutput, const TextBook& printTextBook) {
return TextBookOutput << "TextBook: " << static_cast<const Book&>(printTextBook) << "Grade:" << printTextBook.grade;
}
答案 1 :(得分:0)
return TextBookOutput << static_cast<Book const &>(printTextBook) << ...
答案 2 :(得分:0)
正如其他人指出的那样,你应该使用向下转换来实现你所要求的。但我认为你应该考虑一种不同的方法:你现在正在做的是混合静态和动态多态,这通常不是一个好主意(通常只会在以后表现出来。)
这是问题所在,考虑一下你已经得到了什么:
class Book { ... };
class TextBook : public Book { ... };
ostream& operator<<(ostream& os, const Book& book) {
return os << "Book: " << book.name << "\n";
}
ostream& operator<<(ostream& os, const TextBook& book) {
return os << "TextBook: " << book.name << "\n";
}
如果您像这样使用它,一切都将如预期的那样:
Book book;
TextBook textBook;
cout << book << "\n"; // prints out: Book: XYZ
cout << textBook << "\n"; // prints out: TextBook: XYZ
这是因为编译器将在编译期间(静态)正确地确定书的类型。
现在考虑另一种情况:
Book * textBook = new TextBook();
cout << *textBook << "\n"; // prints out: Book: XYZ !
这是因为编译器无法知道它的更高类型,它可以是Book,TextBook或ChildrensBook。这只能在运行时(动态)使用虚函数等确定。
因此,如果您考虑使用动态多态,我更喜欢这种方法:
class Book {
public:
virtual ostream& print(ostream& os) const { return os << "Book: XYZ"; }
// Don't forget virtual destructor.
virtual ~Book() {}
};
class TextBook : public Book {
public:
virtual ostream& print(ostream& os) const
{
// Here, you can also call the "print" method of the parent class
// like this: os << Book::print(os);
// or just invent your own like this:
return os << "TextBook: XYZ";
}
};
ostream& operator<<(ostream& os, const Book& book) {
// Will correctly decide during runtime whether
// to use Book::print or TextBook::print.
return book.print(os);
}