给定一个基类作为参数,如果传递了派生类,我如何使用 op<< 重载来打印派生类的特征?
Posted
技术标签:
【中文标题】给定一个基类作为参数,如果传递了派生类,我如何使用 op<< 重载来打印派生类的特征?【英文标题】:Given a base class as a parameter, how do I use op<< overload to print the characteristics of a derived class if one is passed? 【发布时间】:2013-03-13 17:46:23 【问题描述】:这是家庭作业。
我有一个基类 Item 和一个派生类 Book。
我在 Item 类中有 op
ostream& operator<<(ostream& out, const Item* const item)
out << item->getName() << endl;
return out;
以及在书类中:
ostream& operator<<(ostream& out, const Book* const b)
out << b->getPages() << endl;
return out;
但是,当我运行我的代码时,只使用了Item
运算符,它不会打印一本书的页面。我已确保打印“书”,而不仅仅是基类。从我读过的材料看来,重载基类和派生类的运算符是你应该做的,所以我不确定为什么我的书信息没有被打印出来。
【问题讨论】:
【参考方案1】:您可以使用多态性而不是重载:向类添加虚拟打印方法:
class Item
public:
virtual void print(std::ostream& o) const
out << getName() << endl;
....
;
class Book : public Item
public:
virtual void print(std::ostream& o) const
out << getPages() << endl;
....
;
然后使用单个ostream& operator<<
:
ostream& operator<<(ostream& out, const Item& item)
item.print(out);
return out;
然后
Item* i1 = new Item(....);
Item* i2 = new Book(....);
std::cout << *i1 << " " << *i2 << std::endl;
delete i1;
delete i2;
【讨论】:
【参考方案2】:如果您更改派生类函数的签名,它不再是基类成员函数的覆盖。
【讨论】:
所以您的意思是通过传入 Book* 而不是 Item* 我不再超载?如果是这样,我如何访问“书籍”特征以从 Item* 参数中显示? 这是正确的 - 覆盖(不是重载,我的错)必须具有相同的签名。另一个答案是正确的。 @user2152382 从您的问题来看,您尝试做的事情还不够清楚,但我提供的解决方案应该可以正常工作。 @SteveTownsend 但无论如何这些都不应该被覆盖,运算符不应该是成员函数。【参考方案3】:“但是在我运行我的代码时只使用了 Item 运算符” - 这种行为可能是因为您将它应用于基类上的指针*/reference& ;
如果你有一个容器,你想在其中存储不同类的实例,这些实例派生自同一个基类并应用于所有这些实例操作符
1.基类中至少有一个虚拟方法(这会导致编译器生成 该类的虚拟表,以后该表可由operator dynamic_cast使用) 2. Enable RTTI (run-time type Identification) in your project : project/c++/language enable RTTI support 3. 实现运算符 使用以下思路:
ostream& operator<<(ostream& out, const Item& item)
if (Book* pBook = dynamic_cast<Book*>(&item)
out << pBook ->getName() << endl;
if (OtherDerivedClassName* pOtherDerivedClass = dynamic_cast<OtherDerivedClassName*>(&item)
// do other interesting things
return out;
【讨论】:
以上是关于给定一个基类作为参数,如果传递了派生类,我如何使用 op<< 重载来打印派生类的特征?的主要内容,如果未能解决你的问题,请参考以下文章