2017-09-27 91 views
0

無論出於何種原因,此參考參數正在返回副本。所以當我改變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; 
    } 
} 
+0

爲什麼'Skill2'等公衆?你爲什麼不使用數組? –

+2

看起來你正試圖給另一個引用'OutWeapon'分配一個引用'Weapon1',它不會做你期望的。在C++中,不可能重新綁定引用。賦值引用總是導致對引用對象的賦值。 – VTT

+0

當你調用'GetWeapon()'時,你爲'OutWeapon'分配內存然後通過。你真正需要的是返回一個指針。 – CinCout

回答

4

重構到

FWeaponSlot& ULoadout::GetWeapon(int32 InIndex) 

是這樣做的合理的,地道,方式。 (C++不允許你重新綁定引用。)

+1

儘管如此,應該提到複製問題仍然存在,如果結果未再次分配給引用。如果目標是具有獨立生命期的另一個類別的成員(即該成員可以在被指定之前存在),它必須是一個指針... – Aconcagua

+0

這不會很好地處理他的「默認」情況... – Sean

+0

@Sean :在這種情況下,我傾向於排除一個例外。 – Bathsheba

0

如果我理解這個正確,引用參數只能用於改變TE對象它引用,但不與在refernce呼叫者分配給不同的對象。爲此,需要一個指針,這可以按如下方式完成。

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

調用者還需要給出要交換的對象的地址。但是,像返回所需對象的引用或僅使用數組索引的不同解決方案可能更容易理解。

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.weapon1s ...

要在特定情況下避免此問題,您需要一個指針而不是:

FWeaponSlot* s = u.getWeapon(0); 

請注意,我默默地改變了簽名(只是爲了方便上調用)...

u仍然是對象的所有者,並會自動清除它們被破壞的時候,所以在這個特定情況下不需要任何類型的智能指針。只要確保你不使用s指針的結束u壽命後...

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

如果你在使用參考設置然後更改方法於:

FWeaponSlot& ULoadout::GetWeapon(int32 InIndex); 

但是,你需要檢查InIndex是方法中是有效的,你有沒有返回值,指示的方式「沒有武器」。我們將向希望在頂部是這樣的的方法:

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

另一種方法是返回一個指針,並有null表示 「沒有武器」:

FWeaponSlot* ULoadout::GetWeapon(int32 InIndex);