运行时的C ++构造函数变量值不会被覆盖

时间:2018-03-15 10:12:50

标签: c++ constructor

我正在跟随Unity学习c ++课程。我跟着讲师,但我在他定义构造函数的部分停了下来。由于某种原因,变量不会在运行时被我在构造函数定义中给出的值覆盖。

这是我的代码:

FBullCowGame.h

#pragma once
//#include <iostream>
#include <string>

class FBullCowGame {
public:
    FBullCowGame();
    void Reset() const; //TODO make a more rich return value
    int GetMaxTries() const;
    int GetCurrentTry() const;
    bool CheckGuessValidity(std::string) const;
    bool IsGameWon() const;

private:
    int MyCurrentTry;
    int MyMaxTries;
};

FBullCowGame.cpp

#include "FBullCowGame.h"

//#pragma region constructors
FBullCowGame::FBullCowGame() {
    int MyCurrentTry = 666;
    int MyMaxTries = 666;
}
//#pragma endregion

//#pragma region getters
void FBullCowGame::Reset() const { return; }
int FBullCowGame::GetMaxTries() const { return MyMaxTries; }
int FBullCowGame::GetCurrentTry() const { return MyCurrentTry; }
bool FBullCowGame::CheckGuessValidity(std::string) const { return false; }
bool FBullCowGame::IsGameWon() const { return false; }
//#pragma endregion

的main.cpp

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

void PrintIntro();
void PlayGame();
std::string GetGuess();
bool AskToPlayAgain();

FBullCowGame BCGame;

int main() {
    std::cout << BCGame.GetCurrentTry();
    std::cout << BCGame.GetMaxTries();
    bool bPlayAgain = false;
    do {
        PrintIntro();
        PlayGame();
        bPlayAgain = AskToPlayAgain();
    } while (bPlayAgain);
    return 0;
}

void PlayGame() {
    int MaxTries = BCGame.GetMaxTries();
    std::cout << MaxTries << "\n";
    for (int i = 1; i <= MaxTries; i++) {
        std::string Guess = GetGuess();
        std::cout << "Your guess was: " << Guess << std::endl;
        std::cout << std::endl;
    }
}

void PrintIntro() {
    constexpr int WORD_LENGTH = 9;
    std::cout << "Welcome to Bulls and Cows, a fun word game.\n";
    std::cout << "Can you guess the " << WORD_LENGTH;
    std::cout << " letter isogram I'm thinking of?\n\n";
    return;
}

//std::cout << "Your guess is: " << Guess << "\n\n";

std::string GetGuess() {
    int CurrentTry = BCGame.GetCurrentTry();
    std::string Guess = "";
    std::cout << "Try " << CurrentTry << ". Enter your guess: ";
    std::getline(std::cin, Guess);
    return Guess;
}

bool AskToPlayAgain() {
    std::cout << "Do you want to play again(y/n)? ";
    std::string Response = "";
    std::getline(std::cin, Response);
    //std::cout << "First char is: " << ((Response[0] == 'y') || (Response[0] == 'Y')) << "\n";
    return (Response[0] == 'y') || (Response[0] == 'Y');
}

我在main中输出这两行的值:

std::cout << BCGame.GetCurrentTry();
std::cout << BCGame.GetMaxTries();

对于getter函数中的两个值,我只得到0。我是c ++的初学者,我需要一些帮助。我认为这是一个IDE问题,所以我清理了解决方案,重建,重新运行,重新启动IDE并再次执行此操作。任何形式的帮助表示赞赏。感谢。

1 个答案:

答案 0 :(得分:1)

在你的课堂宣言中,你有:

{
    ...
private:
    int MyCurrentTry;
    int MyMaxTries;
};

然后在你的构造函数中,你认为你正在使用它来初始化它们:

FBullCowGame::FBullCowGame() {
    int MyCurrentTry = 666;
    int MyMaxTries = 666;
}

但是这里实际发生的是你正在创建与你的类成员具有相同名称的本地堆栈变量。使用类this pointer ->

可以看到您的类成员变量
{
    this->MyCurrentTry ...
    this->MyMaxTries   ...
}

因为这两组变量不一样。您的成员变量甚至没有被初始化;编译器可能足够智能,可以使用0自动初始化它们,但这不能保证,因为它们可以有任意值。您只是声明并初始化仅对构造函数本地的堆栈变量。

要解决此问题,您有3个选项。

首先,评论中已经提到过。只需在构造函数中的名称前删除类型int,这样就不会声明局部变量,而是实际使用这些成员:

{
     MyCurrentTry = 666;
     MyMaxTries   = 666;
}

第二种选择是做同样的事情,但要使用班级的this pointer ->

{
    this->MyCurrentTry = 666;
    this->MyMaxTries   = 666;
}

第三种也是更受欢迎的方法是使用类构造函数的成员初始化列表。

FBullCowGame::FBullCowGame() :
    MyCurrentTry( 666 ),
    MyMaxTries( 666 ) {
}

这应该解释你在类的构造函数中做错了什么,以及为什么变量没有被初始化为你认为它们应该存在的东西,以及为什么你得到你看到的输出。

旁注;你班级的Reset()函数绝对没有任何作用。

如果您想按照自己的想法使用它,那么您会希望它看起来像这样:

// Remove the const qualifier; otherwise you will not able to modify 
// the class's members with this function. "const" is usually good for
// methods that return a member that does not make any internal changes
// to the member or the class.
{
public:
    void Reset();
};


FBullCowGame::Reset() {
    MyCurrentTry = "whatever value to reset it to."
    MyMaxTries   = "whatever value to reset it to."
}