如何在 C++ 中交换父指针和子指针?
How can I swap a parent pointer and a child pointer in c++?
Weapon
继承自 Item
.
weapon
是 class Hero
的成员。我想将它与函数中传递的 item
交换,对于此示例也是 Weapon
(我将添加更多案例)。
void Hero::equip(Item* item){
if(instanceof<Weapon>(item)){std::swap (item, static_cast<Item>(weapon));}
}
基本上,当从英雄的物品栏中装备某些东西时,我希望它存储在 Hero
的相应成员中,并且之前装备的 item
重新存储在库存,无论物品的类型如何。库存是 std::vector<Item*>
,因此它可以容纳多态项目。
向上转换 weapon
似乎不起作用,因为 Item
是虚拟的。我尝试过的所有其他类型的转换也都失败了,一些手动交换它们的尝试也失败了。如果你想知道 instanceof
,我复制了这个模板以便我可以在 C++ 中使用它:
template<typename Base, typename T>
inline bool instanceof(const T *ptr) {
return dynamic_cast<const Base*>(ptr) != nullptr;
}
当我使用 Item*
而不是 Item
时,我得到:
no matching function for call to 'swap(Item*&, Item*)'
std::swap()
将非常量左值引用作为输入,这就是为什么当您尝试与 static_cast<Item*>(weapon)
交换时出现“无匹配函数”错误的原因,这不是 [=66] =]ing 一个可以交换的左值。
为了将新的 item
分配给 weapon
成员,您需要 dynamic_cast
return 的 Weapon*
指针,因此您的 instanceof()
模板在这里没有帮助你。
试试这个:
void Hero::equip(Item* &item) {
if (Weapon *new_weapon = dynamic_cast<Weapon*>(item)) {
Item *old_weapon = weapon;
weapon = new_weapon;
item = old_weapon;
}
}
或者:
void Hero::equip(Item* &item) {
if (Weapon *w = dynamic_cast<Weapon*>(item)) {
std::swap(weapon, w);
item = w;
}
}
或者,如果您使用的是 C++14 或更高版本,则可以改用 std::exchange()
:
void Hero::equip(Item* &item) {
if (Weapon *new_weapon = dynamic_cast<Weapon*>(item)) {
item = std::exchange(weapon, new_weapon);
}
}
注意:使用 Item*&
作为 item
参数假定调用 equip()
时使用 Item*
指针直接 来自 inventory
元素,例如:
hero.equip(hero.inventory[index]);
而不是间接,像这样:
Item *item = hero.inventory[index];
hero.inventory.erase(hero.inventory.begin()+index);
hero.equip(item);
如果传递给 equip()
的 item
不是对 inventory
元素的 直接 引用,那么我会建议使用 equip()
return 旧的 Item*
并让调用者决定如何处理它,例如:
Item* Hero::equip(Item* item) {
if (Weapon *new_weapon = dynamic_cast<Weapon*>(item)) {
Item *old_weapon = weapon;
weapon = new_weapon;
return old_weapon;
}
...
return nullptr;
}
或者:
Item* Hero::equip(Item* item) {
if (Weapon *w = dynamic_cast<Weapon*>(item)) {
std::swap(weapon, w);
return w;
}
...
return nullptr;
}
或者:
Item* Hero::equip(Item* item) {
if (Weapon *new_weapon = dynamic_cast<Weapon*>(item)) {
return std::exchange(weapon, new_weapon);
}
...
return nullptr;
}
然后调用者可以这样做:
Item *item = hero.inventory[index];
hero.inventory.erase(hero.inventory.begin()+index);
item = hero.equip(item);
if (item) hero.inventory.push_back(item);
Weapon
继承自 Item
.
weapon
是 class Hero
的成员。我想将它与函数中传递的 item
交换,对于此示例也是 Weapon
(我将添加更多案例)。
void Hero::equip(Item* item){
if(instanceof<Weapon>(item)){std::swap (item, static_cast<Item>(weapon));}
}
基本上,当从英雄的物品栏中装备某些东西时,我希望它存储在 Hero
的相应成员中,并且之前装备的 item
重新存储在库存,无论物品的类型如何。库存是 std::vector<Item*>
,因此它可以容纳多态项目。
向上转换 weapon
似乎不起作用,因为 Item
是虚拟的。我尝试过的所有其他类型的转换也都失败了,一些手动交换它们的尝试也失败了。如果你想知道 instanceof
,我复制了这个模板以便我可以在 C++ 中使用它:
template<typename Base, typename T>
inline bool instanceof(const T *ptr) {
return dynamic_cast<const Base*>(ptr) != nullptr;
}
当我使用 Item*
而不是 Item
时,我得到:
no matching function for call to 'swap(Item*&, Item*)'
std::swap()
将非常量左值引用作为输入,这就是为什么当您尝试与 static_cast<Item*>(weapon)
交换时出现“无匹配函数”错误的原因,这不是 [=66] =]ing 一个可以交换的左值。
为了将新的 item
分配给 weapon
成员,您需要 dynamic_cast
return 的 Weapon*
指针,因此您的 instanceof()
模板在这里没有帮助你。
试试这个:
void Hero::equip(Item* &item) {
if (Weapon *new_weapon = dynamic_cast<Weapon*>(item)) {
Item *old_weapon = weapon;
weapon = new_weapon;
item = old_weapon;
}
}
或者:
void Hero::equip(Item* &item) {
if (Weapon *w = dynamic_cast<Weapon*>(item)) {
std::swap(weapon, w);
item = w;
}
}
或者,如果您使用的是 C++14 或更高版本,则可以改用 std::exchange()
:
void Hero::equip(Item* &item) {
if (Weapon *new_weapon = dynamic_cast<Weapon*>(item)) {
item = std::exchange(weapon, new_weapon);
}
}
注意:使用 Item*&
作为 item
参数假定调用 equip()
时使用 Item*
指针直接 来自 inventory
元素,例如:
hero.equip(hero.inventory[index]);
而不是间接,像这样:
Item *item = hero.inventory[index];
hero.inventory.erase(hero.inventory.begin()+index);
hero.equip(item);
如果传递给 equip()
的 item
不是对 inventory
元素的 直接 引用,那么我会建议使用 equip()
return 旧的 Item*
并让调用者决定如何处理它,例如:
Item* Hero::equip(Item* item) {
if (Weapon *new_weapon = dynamic_cast<Weapon*>(item)) {
Item *old_weapon = weapon;
weapon = new_weapon;
return old_weapon;
}
...
return nullptr;
}
或者:
Item* Hero::equip(Item* item) {
if (Weapon *w = dynamic_cast<Weapon*>(item)) {
std::swap(weapon, w);
return w;
}
...
return nullptr;
}
或者:
Item* Hero::equip(Item* item) {
if (Weapon *new_weapon = dynamic_cast<Weapon*>(item)) {
return std::exchange(weapon, new_weapon);
}
...
return nullptr;
}
然后调用者可以这样做:
Item *item = hero.inventory[index];
hero.inventory.erase(hero.inventory.begin()+index);
item = hero.equip(item);
if (item) hero.inventory.push_back(item);