如何通过其他 .cpp 文件中的类变量编辑公共成员变量?

Posted

技术标签:

【中文标题】如何通过其他 .cpp 文件中的类变量编辑公共成员变量?【英文标题】:How to edit public member variables via class variable in other .cpp files? 【发布时间】:2012-09-15 08:26:06 【问题描述】:

我和我的朋友正在学习 C++,虽然我们已经能够在这个程序中解决所有遇到的问题(并且通过这样做学到了很多),但这个问题一直让我们绞尽脑汁天。我们花费了无数个小时,不仅试图自己解决它,而且还查看了 *** 的相关问题并进行了大量的谷歌搜索......最后我们决定我们只需要询问并希望你们中的一个人知道我们的问题是什么.

基本上,我们正在尝试创建一个基于文本(仅限控制台)的 RPG,并且我们已经到了使用我们唯一的头文件中定义的类创建玩家统计信息的地步,该类有三个构造函数(当然使用函数重载)虽然我们能够无错误地运行游戏,但似乎我们无法以任何方式实际编辑类成员变量的值!

这是我们的班级:

//File OverHeader.h

class PlayerStatistics

public:
    PlayerStatistics(int HitPoints, int MagickaPoints, int Fatigue, int Damage, int Defense, int Dodge, int Block, int SpellCastChance);
    PlayerStatistics(int Experience, int Level);
    PlayerStatistics();

    int HitPoints;
    int MagickaPoints;
    int Fatigue;
    int Damage;
    int Defense;

    // Chance Based System (Relies on Fatigue Level)
    int Dodge;
    int Block;
    int SpellCastChance;

    int Experience;
    int Level;
;

以及主要功能:

#include <iostream>
#include <string>
#include "OverHeader.h"

// MAIN FUNCTION DEFINITION
int main()

PlayerStatistics PlayerStats(20, 20, 20, 20, 20, 20, 20, 20);
PlayerStatistics PlayerStatsLevel(0, 1);

    //continued with code irrelevant to this question.

问题在于主函数中的行实际上并没有将类中的整数变量设置为这些值。在这两行之后,整数值应设置为(仅用于演示目的):

int HitPoints == 20;
int MagickaPoints == 20;
int Fatigue == 20;
int Damage == 20;
int Defense == 20;
int Dodge == 20;
int Block == 20;
int SpellCostChance == 20;
int Experience == 0;
int Level == 1;

但奇怪的是,输出这些整数中的任何一个都会简单地输出随机数(大概是内存地址当前值)。

这三个构造函数实际上在此处正确定义(虽然不在 Main.cpp 中):

// PlayerCreation.cpp
PlayerStatistics::PlayerStatistics(int HitPoints, int MagickaPoints, int Fatigue, int Damage, int Defense, int Dodge, int Block, int SpellCastChance)




PlayerStatistics::PlayerStatistics(int Experience, int Level)




PlayerStatistics::PlayerStatistics()



这就是我们的问题,我希望我描述得足够清楚,如果你能帮助我们实际编辑这些类成员变量的值,请告诉我!感谢所有帮助!

【问题讨论】:

你需要google的词是“member initializer list” 【参考方案1】:

这会以两种不同的方式创建同一个类:

PlayerStatistics PlayerStats(20, 20, 20, 20, 20, 20, 20, 20);
PlayerStatistics PlayerStatsLevel(0, 1);

第一个创建一个名为PlayerStats 的变量,它使用第一个构造函数。第二个创建另一个名为 PlayerStatsLevel 的变量,它使用第二个构造函数。

现在,构造函数...

// PlayerCreation.cpp
PlayerStatistics::PlayerStatistics(int HitPoints, int MagickaPoints, int Fatigue, int Damage, int Defense, int Dodge, int Block, int SpellCastChance)




PlayerStatistics::PlayerStatistics(int Experience, int Level)



这实际上并没有初始化类中的成员变量。您在构造函数中使用了相同的名称,但这实际上会让您感到悲痛,因为(举一个例子)传递给构造函数的局部变量HitPoints 覆盖了类成员HitPoints。现在,如果你想引用班级成员,你必须使用this-&gt;HitPoints

所以,我重申,实际上没有任何东西被初始化。所以你的对象中有随机值。您需要这样做(我将采用较短的示例):

// Using initializer list
PlayerStatistics::PlayerStatistics(int inExperience, int inLevel)
    : Experience(inExperience), Level(inLevel)
    


// Or using conventional assignment
PlayerStatistics::PlayerStatistics(int inExperience, int inLevel)
    
    Experience = inExperience;
    Level = inLevel;

请注意,其他值未使用此构造函数初始化。这可能是有意的,或者您可能希望将它们全部设置为默认值。您需要明确地执行此操作。

现在,您似乎想要一个包含所有这些统计信息的单个实例。您可能想要做的是只使用一个构造函数 - 空构造函数 PlayerStatistics(),并将所有内容初始化为“合理”的东西。然后定义函数以分块设置统计信息:

void PlayerStatistics::SetStats(int HitPoints, int MagickaPoints, int Fatigue, int Damage, int Defense, int Dodge, int Block, int SpellCastChance)

    this->HitPoints = HitPoints;
    this->MagickaPoints = MagickaPoints;
    // etc etc...


void PlayerStatistics::SetLevel(int Experience, int Level)

    this->Experience = Experience;
    this->Level = Level;


// If you want you can explicitly set the values to something in the constructor.
// It's probably good practice if you're new at this.
PlayerStatistics::PlayerStatistics()
    
    SetStats(0, 0, 0, 0, 0, 0, 0, 0);
    SetLevel(0, 0);

现在在你的主要:

PlayerStatistics player;
player.SetStats(20, 20, 20, 20, 20, 20, 20, 20);
player.SetLevel(0, 1);

或者,如果这些是新玩家的默认设置,请在构造函数中执行,然后您就不需要记住了。

希望能帮助您入门。玩得开心,不要害怕尝试。

【讨论】:

哇!非常感谢您提供令人印象深刻且非常有用的帖子,这完全解决了问题并教会了我一些东西!你是老板,谢谢!【参考方案2】:

那些构造函数没有定义正确:它们接受参数,但不对值做任何事情!试试这个:

PlayerStatistics::PlayerStatistics(int Experience, int Level)
:
  Experience(Experience),
  Level(Level)



大致相当于:

PlayerStatistics::PlayerStatistics(int Experience, int Level)

  this->Experience = Experience;
  this->Level = Level

当然你想以同样的方式初始化其他的,并将未指定的字段设置为默认值,但你明白了。

【讨论】:

嗯,我发了一个回复,但它似乎不起作用。谢谢,我们最初尝试过没有用,并认为没有区别(我们仍在学习中)。我们已经修复了将这些添加到所有构造函数声明的代码。使用此添加进行测试后,输出仍然是随机数......嗯......不过谢谢!【参考方案3】:

您的构造函数不会设置值 - 构造函数可以具有您喜欢的任何参数,并且这些参数不会仅仅因为它们碰巧具有相同的名称而被分配给数据成员。

你需要:

PlayerStatistics::PlayerStatistics(
    int HitPoints, int MagickaPoints, int Fatigue, 
    int Damage, int Defense, int Dodge, int Block, 
    int SpellCastChance) : 
        HitPoints(HitPoints), 
        MagickaPoints(MagickaPoints),
        ... etc ...



(按你喜欢的方式缩进,我这样做是因为我的代码和你的代码之间的唯一区别似乎没有太大的区别,在右侧的滚动条上是不可见的)。

: HitPoints(HitPoints) ... 是一个“初始化列表”,意思是“用那个值初始化这个基类或数据成员”。在您的情况下,该值恰好与数据成员具有相同的名称,但这很好,编译器会从上下文中找出哪个是哪个。

【讨论】:

也感谢您的回复,我们已经修复了代码以包含您和 Thomas 发布的建议,这个故障已经修复很好,但遗憾的是问题仍然存在。 @TorbenC:如果在此更改后问题仍然存在,则可能是您正在调用一个构造函数(体验构造函数),然后查看它未初始化的数据成员(所有来自另一个的)。一般来说,每个构造函数都应该初始化一切。

以上是关于如何通过其他 .cpp 文件中的类变量编辑公共成员变量?的主要内容,如果未能解决你的问题,请参考以下文章

java中的类修饰符成员变量修饰符方法修饰符

MFC如何添加自定义控件

java中的类修饰符成员变量修饰符方法修饰符

java面向对象学习之——java中的类修饰符成员变量修饰符方法修饰符

帮助 C++ 中的类和成员变量

如何从他们自己的类的成员函数中访问公共变量? (C ++)