2016-05-02 16 views
1

私はプレーヤーの名前、正解、プレイヤーが間違った答えを保持するPlayer Classを持っています。 getRight()、getWrong()、addToRight()、またはaddToWrong()関数にアクセスしようとすると、これらの関数内のステートメントで「読み取りアクセス違反:これはnullptrでした」というエラーが表示されます。私はポインタを正しく設定してはいけません。私は何を変えるべきですか?ありがとう!ここで"読み取りアクセス違反:これはnullptrでした"私は正しく割り当てられたと思っています...?

はPlayer.hがここ

#ifndef PLAYER_H 
#define PLAYER_H 
#pragma once 

using namespace std; 
class Player;//FWD declaration 

class Player 
{ 
public: 
    Player(); 
    Player(string playerName); 

    string getName() const 
    { 
     return name; 
    } 

    //These functions show stats from 
    //current round 
    int getRight() const 
    { 
     return right; 
    } 

    int getWrong() const 
    { 
     return wrong; 
    } 

    //These functions update 
    //player info that will be saved 
    //to player profile 
    void setName(string userName); 
    void addToRight(); 
    void addToWrong(); 

private: 
    string name; 
    int right; 
    int wrong; 
}; 
#endif 

をファイルのPlayer.cppファイルです:

#include <iostream> 
#include <iomanip> 
#include <fstream> 
#include "Player.h" 

using namespace std; 

Player::Player() 
{ 
    name = ""; 
    right = 0; 
    wrong = 0; 
} 

Player::Player(string playerName) 
{ 
    ifstream inFile; 
    ofstream outFile; 
    string name = playerName; 
    string fileName = playerName + ".txt"; 

    inFile.open(fileName.c_str()); 
    if (inFile.fail()) 
    { 
     outFile.open(fileName.c_str()); 
     outFile << 0 << endl; 
     outFile << 0 << endl; 
     outFile.close(); 
     inFile.close(); 
     setName(playerName); 
     right = 0; 
     wrong = 0; 

     cout << "Welcome new player!" 
      << " Your statistics profile has been created." << endl; 
    } 
    else 
    { 
     inFile >> right; 
     inFile >> wrong; 
     inFile.close(); 
     setName(playerName); 
     cout << "Welcome back!" << endl; 
    } 
} 

void Player::setName(string userName) 
{ 
    name = userName; 
} 

void Player::addToRight() 
{ 
    right = right + 1; 
} 

void Player::addToWrong() 
{ 
    wrong = wrong + 1; 
} 

そしてここでは、私のメインです:

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

using namespace std; 

void test(Player *player); 

int main() 
{ 
    Player *player = nullptr; 


    test(player); 

    cout << "name: " << player->getName() << endl; 
    cout << "right: " << player->getRight() << endl; 

    player->addToRight(); 

    cout << "right: " << player->getRight() << endl; 

    return 0; 
} 

void test(Player *player) 
{ 
    string name; 

    cout << "name: "; 
    getline(cin, name); 
    player = new Player(name); 
} 

がするクラスを持っていますこれらのアクセス違反を避けるためにポインタを扱うときは、別の方法で設定しますか?ありがとう!

+0

'using namespace std'と書くのは避けてください。 – Destructor

+0

を除いて、オーバーフローするスタックに投稿する例を除いて、それは問題ありません。また、それを.cppファイルに入れるだけであれば、それほど悪くはありません。実際のコードの.hファイルに入れないでください。 – xaxxon

+0

ポインタの使用理由は何ですか?あなたはすべてを書きました。何らかの理由であなたのプログラムに 'Player * 'を導入しました。どうして? – PaulMcKenzie

答えて

5
void test(Player *player) { 
    ... 
    player = new Player(...); 
} 

これは、プレーヤーのローカルコピーのみを変更します。関数外のポインタを変更するには、ポインタ(またはダブルポインタ)を参照する必要があります。代わりに、

void test(Player *& player) {...} 

の代わりに使用してください。

+0

ありがとう!私は、これについての私の頭を包み込むことを試みている質問を続行している: 私は、関数へのポインタをメモリアドレスに向けた関数へのポインタを渡すという印象を受けていました。つまり、パラメータの引数はコピーされませんが、そのアドレスに格納されている値に直接変更が加えられます。プレイヤーはテスト機能の中にコピーされていますか? –

+1

あなたが参照渡ししない限り、C++のすべて(そして常にC言語のすべて)は値渡しとなり、コピーが作成されます。この場合、POINTERのコピーが作成されます。ポインタのコピーは、それが指す内容を元のポインタと同じように変更することができますが、ポインタ自体を変更することはコピーを変更することに過ぎません。 original_ptr-> some_int_field = 1; copy_of_original_ptr_in_function-> some_int_field = 1;どちらも同じことをする。 original_ptr =&some_player_object; original_ptrとcopy_of_original_ptr_in_functionにのみ影響します&some_player_objectはコピーにのみ影響します。 – xaxxon

+1

ポインタ(ダブルポインタ)へのポインタを渡すと、元のポインタが指しているものを変更できるようになりますが、参照は扱いやすくなり、ヌルにならないという利点があります。あなたの状況に適しています。 – xaxxon

関連する問題