1

検索しましたが、欲しいものが見つかりませんでした...

私は小さなゲームをしています。そして、私はstructプレーヤーの詳細を含むこれを手に入れました。

struct Player
{
    string name;
    int level;
    int exp;
    int hp; // life
    int mp; // mana
    int shield;
};

そして、メニューで、ユーザーが新しいゲームを開始することを選択すると、次の機能に移動します。

    int StartNewPlayer(string name)
    {
        Player player;

        player.name = name;
        player.level = 1;
        player.exp = 0;
        player.hp = 20;
        player.mp = 5;
        player.shield = 0;

        *pass/return the struct here*
    }

次に、ゲームボードを印刷する関数があり、新しいプレーヤー構造体からのデータをどこで使用する必要がありますか。たとえば、次のようになります。

void game_board ()
{
    cout << "Hello!" << player.name;

    (...)
}

最後に、main私はどこかにあります:

int main ()
{
    StartNewPlayer(new_game());
    game_board();
}

上記のすべての関数を呼び出します。

しかし、私はそれを理解することができません...私は運がなくて参照、ポインタを試しました..私はここでいくつかの助けが必要です...

4

3 に答える 3

2

これはどう?

Player StartNewPlayer(string name)
{
    Player player;

    player.name = name;
    player.level = 1;
    player.exp = 0;
    player.hp = 20;
    player.mp = 5;
    player.shield = 0;

    return player;
}

void game_board(Player player)
{
    cout << "Hello!" << player.name;

    (...)
}

int main ()
{
    Player player = StartNewPlayer(new_game());
    game_board(player);
}
于 2013-02-28T19:53:03.767 に答える
1

値渡しを使用して、複雑なデータ型のデータの余分なコピーを作成しないでください

代わりにポインタを使用して、関数で変更できる変数のアドレスを渡します。変更は、呼び出し元の関数にも反映されます。

void StartNewPlayer(string name, Player *player)
{
    player->name = name;
    player->level = 1;
    player->exp = 0;
    player->hp = 20;
    player->mp = 5;
    player->shield = 0;
}

void game_board(Player* player)
{
    cout << "Hello!" << player->name;

    (...)
}

int main ()
{
    Player player;
    StartNewPlayer(new_game(), &player);
    game_board(&player);
}

参照渡しを使用する代替方法:

あなたが参照のファンなら(これは単に内部的にポインタを利用する巧妙なコンパイラトリックです):

void StartNewPlayer(string name, Player& player)
{
    player.name = name;
    player.level = 1;
    player.exp = 0;
    player.hp = 20;
    player.mp = 5;
    player.shield = 0;
}

void game_board(Player& player)
{
    cout << "Hello!" << player.name;

    (...)
}

int main ()
{
    Player player;
    StartNewPlayer(new_game(), player);
    game_board(player);
}
于 2013-02-28T19:56:23.557 に答える
-1

Player構造体へのポインターを返すことをお勧めします。現在行っているように「参照」を返すと、Playerのコピーコンストラクターが呼び出され、さらに複雑になる可能性があります。

通常、StartNewPlayer(...)の終わりに、オブジェクトスコープが終了するため、そこで宣言したPlayerは存在しなくなります。したがって、それを返すと、c ++コンパイラは、オブジェクトを存続させたいと認識し、作成します。目に見えないあなたのためのコピー。ポインタを返すと、実際には関数で割り当てたオブジェクトが返されます。

プレーヤー構造に次のようなポインターがあるとします。

struct Player
{
  int level;
  char* name; //lets assume you did it like that
}

プレーヤーを返すとき、intはコピーされますが、char*はコピーされません。intは扱いやすいですが、char*にはstrlenやなどのあらゆる種類のトリッキーな関数が必要strncpyです。Player構造体が複雑になるほど、デフォルトのコピーコンストラクターを使用することで直面する問題が多くなります。

もう1つの解決策は、Player構造体のコピーコンストラクターを自分で宣言することです(実際には、クラスはc ++でほとんど交換可能であるため、クラスを使用できます)。

Player(const Player& p)
{
    name = p.name;
    level = p.level;
    // and so forth
}

だから私は使用します

Player* StartNewPlayer(std::string name)
{
    Player* player = new Player();
    player->name = name;
    player->level = 1;
    // snip 
    return player;
}

プログラムの最後にdelete player、メモリリークが発生することを確認してください。

于 2013-02-28T20:05:13.793 に答える