【问题标题】:static Object Pointer静态对象指针
【发布时间】:2019-01-10 13:18:48
【问题描述】:

我想在方法中创建一个静态对象。该方法的类有一个指针,其类型为 Player。 Phayer 是一个抽象类。现在我想让指针指向一个继承自 Player 的对象。当 Methode 关闭时,该引用不应丢失。 指针是这样初始化的:

pragma once
include "Player.h"
include "Matchfield.h"

class Game
{

public:
    Game();
    ~Game();
    void start();
private:
    Player *playerone;
    Player *playertwo;
    Matchfield gamefield;
};

现在我正在这样做:

    Game::Game()
{
    for (int i = 0; i < 2; i++) {
        switch (CLI::getplayer())
        {
        case 0:
        {
            static HumanPlayer x;
            playerone = &x;
        }
        case 1:
        {
            BotOne x;
            playerone = &x;
        }

        default:
            break;
        }
    }
}

然后另一个方法尝试从指针引用的对象调用方法。

int actMove;
    int inheight;
    while (true) {
        actMove = playerone->play(gamefield);
        inheight = gamefield.columnHeight(actMove);
... Bla Bla just boring stuff

我得到一个错误,找不到我的对象,为什么?不是静态的吗?

谢谢你的回答,我很感激!:)

为问题添加简约示例:

class Player
{
public:
    Player() = default;
    ~Player() = default;
    virtual int play(Matchfield ActField) = 0;
    bool ishuman;
};

Game::Game()
{

    static HumanPlayer x;
    playerone = &x;

}

HumanPlayer 不是一个抽象类; 现在我想在其他地方使用指针 Playerone。 例如这里; 在 Humanplayer 中玩会返回一个 int;

int Game::play(){
return = playerone->play();
}

【问题讨论】:

  • 1) 请提供minimal reproducible example。 2)“Isn't static?BotOne x; 不是静态的,当它离开(case 1)范围时,playerone 中会留下一个悬空指针,并且它的任何用法都会调用未定义的行为。 3) playertwo 甚至没有被初始化,因此它的任何使用都会调用未定义的行为。
  • 为什么要为playerone设置一个钓鱼指针。 HumanPlayer 是静态的。我在这里遇到了问题:actMove = playerone->play(gamefield);
  • 这就是为什么我要minimal reproducible example。我不知道你的 CLI::getplayer() 返回什么。如果它返回1,则playerone 会留下一个悬空指针,因为BotOne x; 不是静态的。
  • 无论如何,您在 for 循环中创建的 HumanPlayer 和 BotOne 对象不存在于您的 for 循环上下文之外,因此您首先会遇到概念错误。
  • @BenjaminBarrois HumanPlayer object 确实,在switch case 完成执行(以及循环)后仍然存在,因为它是staticBotOne 不是静态的,因此,是的,它确实会在其作用域结束后被销毁。

标签: c++ pointers memory static


【解决方案1】:

回答您关于类中的static 指针的问题:
头文件:

class Game
{
public:
    Game();
    ~Game();
    void start();
private:
    static Player *playerone;
    static Player *playertwo;
    Matchfield gamefield;
};

源文件:

Player * Game::playerone = nullptr;
Player * Game::playertwo = nullptr;

Game::Game()
{ ; }

Game::~Game()
{
  delete playerone;
  delete playertwo;
}

void Game::start()
{
  delete playerone;
  delete playertwo;
  // Example:
  playerone = new Human;
  playertwo = new Bot;
}

由于指针是变量,它们遵循与类中的静态变量相同的语法。

static 关键字意味着所有Game 实例和其派生类的实例都有一个实例。他们都共享相同的playeroneplayertwo

编辑 1:方法中的静态
方法中的static 变量只能在方法内访问。 static 关键字表示变量在执行离开函数后将存在。因此,下次输入函数时,变量将具有与上次执行函数时相同的值。

void AddOne()
{
    static int value = 0;
    std::cout << "Previous value: " << value << "\n";
    ++value;
    std::cout << "Value after add: " << value << "\n\n";
}

int main()
{
  AddOne();
  AddOne();
  AddOne();
  AddOne();
  return 0;
}

上面的代码演示了static变量的生命周期。

【讨论】:

  • 嘿,谢谢您的回答。它帮助了我!我的问题是我有不同的机器人。用户将选择一个机器人。我想实现玩家可以决定使用哪个机器人。所以我想让一个方法让 Point 引用从 Player 继承的不同对象成为可能,具体取决于要使用的机器人。这可能吗?
  • 是的,要么在start 方法中提示用户,要么将它们作为参数传递给start 方法。见std::shared_ptr
【解决方案2】:

您可以将指针声明为静态的,这样当它退出方法时它不会丢失引用,但是每当您实例化Game 类型的对象时,指针就会被该值填充。你可以这样做:

class Game
{

public:
    Game();
    ~Game();
    void start();
private:
    static Player *playerone;
    static Player *playertwo;
    Matchfield gamefield;
};

【讨论】:

  • 我怎样才能不丢失退出方法的参考?对于 Playerone?
  • 你可以这样做:class Game { public: Game(); 〜游戏();无效开始();私人:静态播放器*playerone;静态播放器 *playertwo;赛场比赛场; };
猜你喜欢
  • 2016-02-03
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-08-19
  • 1970-01-01
  • 1970-01-01
  • 2013-02-10
  • 2022-09-30
相关资源
最近更新 更多