参考参数返回副本

时间:2017-09-27 09:23:48

标签: c++

无论出于何种原因,此引用参数都返回一个副本。因此,当我将OutWeapon改为索引0时,它不会影响Weapon1。我做错了吗?

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;
    }
}

5 个答案:

答案 0 :(得分:4)

重构为

FWeaponSlot& ULoadout::GetWeapon(int32 InIndex)

这是明智的,惯用的方式。 (C ++不允许重新绑定引用。)

答案 1 :(得分:0)

如果我理解正确,那么引用参数只能用于改变它引用的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;
    }
}

调用者还需要提供要交换的对象的地址。但是,不同的解决方案(如返回对所需对象的引用或仅使用数组索引)可能更容易理解。

答案 2 :(得分:0)

考虑如何调用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仍然是对象的所有者,并在被销毁时自动清理它们,因此在这种特定情况下不需要任何类型的智能指针。只需确保在s的生命周期结束后不使用u指针...

答案 3 :(得分:0)

虽然采用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]; }
};

答案 4 :(得分:0)

如果您已开始使用引用,请将方法更改为:

FWeaponSlot& ULoadout::GetWeapon(int32 InIndex);

但是,您需要检查InIndex在方法中是否有效,因为您无法返回指示"没有武器的值"。您可以在方法的顶部想要这样的东西:

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

另一种选择是返回指针,让null表示"没有武器":

FWeaponSlot* ULoadout::GetWeapon(int32 InIndex);