参考参数返回副本

Reference parameter returning copy

本文关键字:副本 返回 参数 参考      更新时间:2023-10-16

无论出于何种原因,此参考参数正在返回副本。因此,当我更改索引0的Outweapon时,它不会影响武器1。我做错了吗?

class ULoadout
{
public:
    ULoadout();
    FWeaponSlot Weapon1;
    FWeaponSlot Weapon2;
    FWeaponSlot Weapon3;
    FWeaponSlot Weapon4;
    FSkillSlot Skill1;
    FSkillSlot Skill2;
    FSkillSlot Skill3;
    FSkillSlot Skill4;
    void GetWeapon(int32 InIndex, FWeaponSlot& OutWeapon);
    void GetSkill(int32 InIndex, FSkillSlot& OutSkill);
};
void ULoadout::GetWeapon(int32 InIndex, FWeaponSlot& OutWeapon)
{
    switch (InIndex)
    {
    case 0:
        OutWeapon = Weapon1;
        break;
    case 1:
        OutWeapon = Weapon2;
        break;
    case 2:
        OutWeapon = Weapon3;
        break;
    case 3:
        OutWeapon = Weapon4;
        break;
    default:
        break;
    }
}

重构

FWeaponSlot& ULoadout::GetWeapon(int32 InIndex)

是这样做的明智和惯用方式。(C 不允许您重新启用参考。)

如果我正确理解了这一点,则只能使用参考参数来改变其引用的te对象,但不能将呼叫者中的引用分配给另一个对象。为此,需要一个指针,可以如下完成。

void ULoadout::GetWeapon(int32 InIndex, FWeaponSlot*& OutWeapon)
{
    switch (InIndex)
    {
    case 0:
        OutWeapon = &Weapon1;
        break;
    case 1:
        OutWeapon = &Weapon2;
        break;
    case 2:
        OutWeapon = &Weapon3;
        break;
    case 3:
        OutWeapon = &Weapon4;
        break;
    default:
        break;
    }
}

呼叫者还需要提供要交换对象的地址。但是,一个不同的解决方案,例如返回对所需对象的引用或简单地使用数组索引可能更容易理解。

考虑如何调用getWeapon函数:

ULoadout u; // where ever you got it from...
FWeaponSlot s; // you need a true object!!!
u.getWeapon(0, s); // now you pass the true object in as reference!

getWeapon中现在发生的有效的是:

s = weapon1;

请注意s是一个对象,而不是参考,因此您将u.weapon1复制到s ...

要避免在特定情况下,您需要指针:

FWeaponSlot* s = u.getWeapon(0);

请注意,我默默地更改了签名(只是为了方便电话)...

u仍然是对象的所有者,并将在被销毁时自动清理它们,因此在这种特定情况下无需任何智能指针。只要确保您在u的寿命结束后不使用s指针...

,而服用FWeaponSlot*&可以解决您的问题,但我建议使用常规Getter:

class ULoadout
{
    FWeaponSlot weapons[4];
    FSkillSlot skills[4];
public:
    ULoadout();
    const FWeaponSlot& GetWeapon(int32 index) const { return weapons[index]; }
    FWeaponSlot& GetWeapon(int32 index) { return weapons[index]; }
    const FSkillSlot& GetSkill(int32 index) const { return skills[index]; }
    FSkillSlot& GetSkill(int32 index) { return skills[index]; }
};

如果您设置了使用引用,则将方法更改为:

FWeaponSlot& ULoadout::GetWeapon(int32 InIndex);

但是,您需要检查InIndex在方法中是否有效,因为您无法返回指示"无武器"的值。P>

if(InIndex > 3) throw std::out_of_range("invalid weapon index");

另一种选择是返回指针,并具有null表示"无武器":

FWeaponSlot* ULoadout::GetWeapon(int32 InIndex);