我有一个基础类Item和一个派生类Weapon&Shield。都重载<<。
// item(base) operator overload
ostream& operator<<(ostream& os, const Item& a_item)
{
os << " Item Object - " << endl;
os << " Name: " << a_item.m_name << endl;
os << " Cost: " << a_item.m_cost << endl;
os << " Purpose: " << a_item.m_purpose << endl;
return os;
}
并且:
// weapon(derived) operator overload
ostream & operator<<(ostream & os, const Weapon & a_weapon)
{
os << "Weapon - " << endl;
os << " Name: " << a_weapon.m_name << endl;
os << " Cost: " << a_weapon.m_cost << endl;
os << " Purpose: " << a_weapon.m_purpose << endl;
return os;
}
// shield(derived) operator overload
ostream & operator<<(ostream & os, const Shield & a_shield)
{
os << "Shield - " << endl;
os << " Name: " << a_shield.m_name << endl;
os << " Cost: " << a_shield.m_cost << endl;
os << " Purpose: " << a_shield.m_purpose << endl;
return os;
}
现在,我有一个vector<Item> inventory
,在其中添加了武器和盾牌。当我遍历库存并列出项目时,我得到了Item运算符,而不是那个特定项目的那个。这是我叫喊的方式:
// person(derived) operator overload
ostream& operator<<(ostream& os, const Person& a_person)
{
os << "Person Object - " << endl;
os << " Name: " << a_person.m_name << endl;
os << " Level: " << a_person.m_level << endl;
os << " Hit Points: " << a_person.m_hit_points << endl;
os << " Inventory: " << endl;
for (auto i = 0; i < a_person.m_inventory.size(); i++)
{
os << " " << a_person.m_inventory[i] << endl;
}
return os;
}
我的问题是为什么它调用基数的运算符重载,而不是派生的?可以告诉它从派生类中调用它吗?
答案 0 :(得分:5)
除了object slicing problem之外,您的代码还遇到另一个概念性问题。当您引用基类时,您期望在运行时调用派生类型的operator<<
函数是没有根据的。因为函数不是多态的,所以这行不通。
您必须稍微改变策略以使其像多态函数一样工作。
operator<<
函数。virtual
个成员函数来完成实际工作。virtual
函数调用operator<<
成员函数。说明代码:
struct Base
{
virtual std::ostream& print(std::ostream& os) const
{
// Print base class details
return os;
}
};
struct Derived : Base
{
virtual std::ostream& print(std::ostream& os) const
{
// Do the base class printing first
Base::print(os);
// Print the derived class details.
return os;
}
};
std::ostream& operator<<(std::ostream& os, Base const& b)
{
// This will be a polymorphic call.
return b.print(os);
}
答案 1 :(得分:2)
std::vector
将其元素保留在自己的私有数组中,因此它们按值存储。类型Item
的值始终将Item
作为其最派生的类,因此,当您在其中存储Weapon
时,向量中保留的只是一个Item
( Item
-Weapon
的一部分),并且在打印时只能报告为Item
。