首页 > 解决方案 > 为什么函数参数的行为类似于变量声明?

问题描述

我正在使用 Unreal 并遇到了一些奇怪的错误。我最终发现只需重命名我的函数参数即可解决问题。这是完整的标题和类。问题是InitCard功能:



#pragma once

#include "CoreMinimal.h"
#include "GameFramework/Actor.h"
#include "Components/StaticMeshComponent.h"
#include "Playing_Card.generated.h"

UCLASS()
class BLACKJACK_API APlaying_Card : public AActor
{
    GENERATED_BODY()

    
public: 
    enum Suit { HEARTS = 0, DIAMONDS = 1, CLUBS = 2, SPADES = 3, UNASSIGNED = 4 };
    Suit suit = Suit::UNASSIGNED;

    // Sets default values for this actor's properties
    APlaying_Card();

    int rank;
    int value;

    void InitCard(int rank, Suit suit);
    
    FString faceStr = "";

    UPROPERTY(VisibleAnywhere, BlueprintReadWrite)
    UStaticMeshComponent* mesh;


protected:
    // Called when the game starts or when spawned
    virtual void BeginPlay() override;

public: 
    // Called every frame
    virtual void Tick(float DeltaTime) override;

};

Playing_Card.cpp:




#include "Playing_Card.h"


int rank = 0;
int value = 0;

// Sets default values
APlaying_Card::APlaying_Card()
{
    // Set this actor to call Tick() every frame.  You can turn this off to improve performance if you don't need it.
    PrimaryActorTick.bCanEverTick = true;

    mesh = CreateDefaultSubobject<UStaticMeshComponent>(TEXT("mesh"));

    RootComponent = mesh;

    mesh->SetScalarParameterValueOnMaterials(TEXT("card_index"), 4);    
}



void APlaying_Card::InitCard(int rank, Suit suit)
{
    this->rank = rank;
    this->suit = suit;

    if (rank == 1)
    {
        value = rank; //todo: find a way to make Ace 1 or 11.
        faceStr = "Ace";
    }
    else if (rank <= 10)
    {
        value = rank;
        faceStr = FString::FromInt(rank);
    }
    else if (rank == 11)
    {
        value = 10;
        faceStr = "Jack";
    }
    else if (rank == 12)
    {
        value = 10;
        faceStr = "Queen";
    }
    else if (rank == 13)
    {
        value = 10;
        faceStr = "King";
    }

}

// Called when the game starts or when spawned
void APlaying_Card::BeginPlay()
{
    Super::BeginPlay();
    
}

// Called every frame
void APlaying_Card::Tick(float DeltaTime)
{
    Super::Tick(DeltaTime);

}

这给出了错误: error C4458: declaration of 'rank' hides class member

但是,如果我更改函数参数名称(下面发布的函数),则代码编译时不会出错。

    /// It works! Just by changing parameter names (note: I still use this->rank)
void APlaying_Card::InitCard(int cardRank, Suit cardSuit)
{
    this->rank = cardRank;
    this->suit = cardSuit;

    if (rank == 1)
    {
        value = rank; //todo: find a way to make Ace 1 or 11.
        faceStr = "Ace";
    }
    else if (rank <= 10)
    {
        value = rank;
        faceStr = FString::FromInt(rank);
    }
    else if (rank == 11)
    {
        value = 10;
        faceStr = "Jack";
    }
    else if (rank == 12)
    {
        value = 10;
        faceStr = "Queen";
    }
    else if (rank == 13)
    {
        value = 10;
        faceStr = "King";
    }

}

当我第一次尝试使用这些名称时,导致错误的原因是什么?

标签: c++unreal-engine4

解决方案


在原始代码中,全局变量rank/ suit、类成员rank/suit和参数rank/suit都在InitCard(). 那么您希望编译器在语句的右侧使用this->rank = rank; this->suit = suit;哪些?它不会是类成员,而是函数参数,因为它们在本地范围内。并且编译器会警告您,因为它们与类成员具有相同的名称。

删除全局变量并重命名参数可以避免任何歧义。因此,将使用其成员初始化列表在其构造函数中初始化类,而不是单独的Init方法:

UCLASS()
class BLACKJACK_API APlaying_Card : public AActor
{
...
public: 
    ...
    APlaying_Card(int rank, Suit suit);
    ...
};
APlaying_Card::APlaying_Card(int rank, Suit suit) :
    rank(rank), suit(suit) // <-- no ambiguity here! 
{
    ...

    if (rank == 1)
    {
        value = rank; //todo: find a way to make Ace 1 or 11.
        faceStr = "Ace";
    }
    else if (rank <= 10)
    {
        value = rank;
        faceStr = FString::FromInt(rank);
    }
    else if (rank == 11)
    {
        value = 10;
        faceStr = "Jack";
    }
    else if (rank == 12)
    {
        value = 10;
        faceStr = "Queen";
    }
    else if (rank == 13)
    {
        value = 10;
        faceStr = "King";
    }
}

推荐阅读