c++ - 为什么函数参数的行为类似于变量声明?
问题描述
我正在使用 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";
}
}
当我第一次尝试使用这些名称时,导致错误的原因是什么?
解决方案
在原始代码中,全局变量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";
}
}
推荐阅读
- javascript - Powershell 脚本。如何在浏览器中触发输入字段更改事件?
- scala - Scala GADT Fantom 类型解释器错误:找到任何必需的 A
- javascript - 拒绝运行 JavaScript URL,因为它违反了以下内容安全策略指令
- c# - ASP.net 核心身份复杂声明身份验证
- java - 创建日记应用程序但无法从文本视图中获取要保存在 firebase 数据库中的文本
- c++ - 将数字从文件存储到数组 RECURSION
- c - 数组get被while循环覆盖,它们都有相同的数据
- java - 为什么 Java 类加载器执行“静态”内容,例如 Class.forName
- php - 将 AJAX 视图响应返回到刀片
- android - 在每次注册时创建一个新用户并将新数据添加到 firebase 数据库