派生类中的运算符重新定义但仍使用父类
Operators in derived class redefining but still using parent class
具体来说,我希望能够在基类的两个派生类中使用ostream
operator <<
。
我正在创建的程序应该在"虚拟商店"中打印出各种"产品"的产品详细信息。产品中有两种不同类型的书籍。这些书中的每一本书都应该有自己的:
ID number
Author
NumberOfPages
Year
此外,ChildrensBook
型需要保持最低年龄,TextBook
需要保持等级。
我定义了类 Book
并从中派生出类 ChildrensBook
和 TextBook
。我的问题是关于使用ostream
operator <<
打印出信息。
我可以在 Book 类中定义一个泛型<<函数,该函数将打印出两个派生类共有的所有信息,然后在派生类中重新定义<<时引用它?
例如
//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;
}
所以我想我的问题可以总结为:我可以从子运算符中调用父运算符吗,如果是,我使用什么语法?
我想到的另一个想法是为使用父打印运算符的子级编写一个函数,然后从子级的打印运算符中调用该函数。 这意味着我在重新定义运算符时没有尝试调用运算符,但仍然要求使用父运算符并单独重新定义子运算符。
当然。
您有一个用于 Book
s 的运算符,因此请使用它。您可以通过为它提供对一本书的引用来调用它,并且您可以使用多态性的力量来获取对基础的引用。
ostream& operator<<(ostream& TextBookOutput, const TextBook& printTextBook) {
return TextBookOutput << "TextBook: " << static_cast<const Book&>(printTextBook) << "Grade:" << printTextBook.grade;
}
return TextBookOutput << static_cast<Book const &>(printTextBook) << ...
正如其他人指出的那样,您应该使用向下投射来实现您的要求。但我认为你也应该考虑一种不同的方法:你现在正在做的是混合静态和动态多态性,这通常不是一个好主意(通常只会在以后表现出来)。
这是问题所在,请考虑您已经拥有的内容:
如果您像这样使用它,一切都会按预期进行: 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);
}
- 从类继承时,继承的类是否会通过父类重新定义继承的变量
- 从父类方法返回子类对象
- c++, 在子类中,如何在没有对象的情况下访问父类的方法?
- 将父类对象强制转换为子类的问题
- 在父类中为多个子类定义方法
- 是否有 lint 工具可以检查子类虚拟函数是否与父类定义匹配?
- C 不能将带有父类指针作为类型的静态模板成员定义引用
- 在父类中声明并在子类中定义
- 为什么要将父类定义为友元类
- 获取定义为父类的子类以输出子函数
- 为什么要将子类定义为其自己的父类的好友
- 在子类中定义一个属性,然后在父类中使用它,这在PHP中是一种奇怪的行为
- 不能在嵌套类中使用父类 - 即使之后定义了嵌套类
- 在类中使用typedef定义指向父类函数的函数指针
- C++:包含父类时出现多定义错误
- 如何在不把内部类的定义放入父类的情况下创建一个内部类
- 调用父类的构造函数给出未定义
- 使用=将已定义的父类转换为子类
- 派生类中的运算符重新定义但仍使用父类
- 对父类中方法的未定义引用