C++ “读取访问冲突:这是nullptr”认为我正确分配了它。。。?

C++ “读取访问冲突:这是nullptr”认为我正确分配了它。。。?,c++,function,class,pointers,nullreferenceexception,C++,Function,Class,Pointers,Nullreferenceexception,我有一个玩家类,包含玩家的名字、正确答案和错误答案。当我尝试访问getRight、GetError、addToRight或addToWrong函数时,我得到一个错误,上面写着“读取访问冲突”:这些函数中的语句中的这是nullptr。我一定没有正确设置指针。我应该做什么改变?谢谢 这是Player.h文件 #ifndef PLAYER_H #define PLAYER_H #pragma once using namespace std; class Player;//FWD declarati

我有一个玩家类,包含玩家的名字、正确答案和错误答案。当我尝试访问getRight、GetError、addToRight或addToWrong函数时,我得到一个错误,上面写着“读取访问冲突”:这些函数中的语句中的这是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);
}
在处理指针时,类是否必须进行不同的设置以避免这些访问冲突?谢谢

void test(Player *player) {
    ...
    player = new Player(...);
}
这只会更改播放器的本地副本。要在函数外部更改指针,需要引用指针或双指针。使用:

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

这只会更改播放器的本地副本。要在函数外部更改指针,需要引用指针或双指针。使用:

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


相反。

避免使用命名空间std.进行写入,除非您在示例中发布到堆栈溢出。。那就好了。另外,如果你只把它放在.cpp文件中,那就没那么糟糕了——只是永远不要把它放在真实代码的.h文件中。使用指针的原因是什么?你写了所有东西,然后出于某种原因在你的程序中引入了一个播放器。为什么?@xaxxon:为什么它永远不应该放在真实代码的.h文件中?它有什么问题?因为它会感染后面包含的所有其他.h文件-包括包含.h文件的内容,然后是其他内容。名称空间避免命名冲突,但如果您在第三方库上强制使用using指令,则它可能会发生冲突,并且由于std::和此库中的不明确符号而停止编译-简言之,习惯键入std::并不难。避免使用名称空间std编写。除非在示例中您发布到堆栈溢出。。那就好了。另外,如果你只把它放在.cpp文件中,那就没那么糟糕了——只是永远不要把它放在真实代码的.h文件中。使用指针的原因是什么?你写了所有东西,然后出于某种原因在你的程序中引入了一个播放器。为什么?@xaxxon:为什么它永远不应该放在真实代码的.h文件中?它有什么问题?因为它会感染后面包含的所有其他.h文件-包括包含.h文件的内容,然后是其他内容。名称空间可以避免命名冲突,但如果您在第三方库上强制使用using指令,则它可能会发生冲突,并且由于std::中的符号不明确而停止编译。简而言之,在这个库中,习惯键入std::并不是那么难。谢谢!我有一个后续问题,只是想把我的头绕在这个问题上:我的印象是,传递一个指向函数的指针会将该函数指向一个内存地址。我的意思是不会复制参数参数,但任何更改都会直接对存储在该地址的值进行。在测试函数中复制了播放器吗?除非你通过引用,C++中的所有东西和C中的所有东西都是通过值传递的,这是一个拷贝。在这种情况下,将创建指针的副本。指针的副本可以像修改原始指针一样修改它指向的内容,但是修改指针本身就是修改副本。原始\u ptr->some\u int\u字段=1;并在函数->某些内部字段=1中复制\u原始\u ptr\u的\u;两者都做同样的事情。原始\u ptr=&some\u player\u object;仅影响原始\u ptr和复制\u函数中的\u原始\u ptr\u=&某些\u播放器\u对象仅影响复制。如果将指向指针的指针传递给双指针,则允许您更改原始指针指向的对象,但是参考资料往往更容易处理,并且具有不可以为空的优势——这在你的情况下是合适的。想象一下——我把我的房子地址写在一张纸上。我的记忆力不好,所以我需要保留我的记忆,但我把那张纸复印了一份交给你。如果你在那张纸的复印件上写一个新的门牌号,我仍然知道如何带着我的原件去我家。但是如果你去我的房子,把它漆成红色,那么实际的房子就是红色的——不管你用谁的地址副本去那所房子。如果相反,我们共享那张纸,然后双方都开始开车,而你在那张共享的纸上改了地址,那么我们最终都会在不同的房子里。谢谢!我有一个后续问题,只是想把我的头绕在这个问题上:我的印象是,传递一个指向函数的指针会将该函数指向一个内存地址。我的意思是不会复制参数参数,但任何更改都会直接对存储在该地址的值进行。在测试函数中复制了玩家吗?除非你通过引用,C++中的所有东西和C中的所有东西都是通过值的。
复制一份。在这种情况下,将创建指针的副本。指针的副本可以像修改原始指针一样修改它指向的内容,但是修改指针本身就是修改副本。原始\u ptr->some\u int\u字段=1;并在函数->某些内部字段=1中复制\u原始\u ptr\u的\u;两者都做同样的事情。原始\u ptr=&some\u player\u object;仅影响原始\u ptr和复制\u函数中的\u原始\u ptr\u=&某些\u播放器\u对象仅影响复制。如果将指向指针的指针传递给双指针,则允许您更改原始指针指向的对象,但是参考资料往往更容易处理,并且具有不可以为空的优势——这在你的情况下是合适的。想象一下——我把我的房子地址写在一张纸上。我的记忆力不好,所以我需要保留我的记忆,但我把那张纸复印了一份交给你。如果你在那张纸的复印件上写一个新的门牌号,我仍然知道如何带着我的原件去我家。但是如果你去我的房子,把它漆成红色,那么实际的房子就是红色的——不管你去那所房子的地址是谁的。如果相反,我们共享了那张纸,双方都开始开车,而你更改了那张纸上的地址,那么我们最终都会在不同的房子里。