C++ “读取访问冲突:这是nullptr”认为我正确分配了它。。。?
我有一个玩家类,包含玩家的名字、正确答案和错误答案。当我尝试访问getRight、GetError、addToRight或addToWrong函数时,我得到一个错误,上面写着“读取访问冲突”:这些函数中的语句中的这是nullptr。我一定没有正确设置指针。我应该做什么改变?谢谢 这是Player.h文件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
#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对象仅影响复制。如果将指向指针的指针传递给双指针,则允许您更改原始指针指向的对象,但是参考资料往往更容易处理,并且具有不可以为空的优势——这在你的情况下是合适的。想象一下——我把我的房子地址写在一张纸上。我的记忆力不好,所以我需要保留我的记忆,但我把那张纸复印了一份交给你。如果你在那张纸的复印件上写一个新的门牌号,我仍然知道如何带着我的原件去我家。但是如果你去我的房子,把它漆成红色,那么实际的房子就是红色的——不管你去那所房子的地址是谁的。如果相反,我们共享了那张纸,双方都开始开车,而你更改了那张纸上的地址,那么我们最终都会在不同的房子里。