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

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了运行时的C ++构造函数变量值不会被覆盖[关闭]相关的知识,希望对你有一定的参考价值。

我正在跟随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 << "
";
    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.
";
    std::cout << "Can you guess the " << WORD_LENGTH;
    std::cout << " letter isogram I'm thinking of?

";
    return;
}

//std::cout << "Your guess is: " << Guess << "

";

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')) << "
";
    return (Response[0] == 'y') || (Response[0] == 'Y');
}

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

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

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

答案

在您的课堂声明中,您有:

{
    ...
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."
}

以上是关于运行时的C ++构造函数变量值不会被覆盖[关闭]的主要内容,如果未能解决你的问题,请参考以下文章

C ++复制构造函数中的异常[关闭]

请教一下C#中父类静态构造函数在子类中为啥不会和子类的静态构造函数一起执行

Java学习之继承关系内存分配

面对对象

在 C++0x 中,非静态数据成员初始化器会覆盖隐式复制构造函数吗?

SQLERRM 正在被覆盖