给定一个基类作为参数,如果传递了派生类,我如何使用 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&amp; operator&lt;&lt;

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<< 重载来打印派生类的特征?的主要内容,如果未能解决你的问题,请参考以下文章

如果派生类作为基类返回,如何访问派生类的方法?

为啥当我有两个函数时编译器没有显示错误,一个将基类作为参数,一个将派生类作为参数?

如何从基类调用派生赋值运算符?

给定基类方法的编译时覆盖

将派生类传递给基类参数的函数

将派生对象作为参数传递[关闭]