Tengo un Jugador de la Clase que contiene el nombre del jugador, a la derecha de las respuestas,y las respuestas incorrectas del jugador conseguido. Cuando intento acceder getRight(), getWrong(), addToRight(), o addToWrong funciones() me sale un error que dice, «Leer infracción de acceso: este fue nullptr» en las instrucciones dentro de esas funciones. No debo ser la configuración de mi puntero correctamente. ¿Qué cambios debo hacer? Gracias!

Aquí está el Jugador.h archivo

#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

Aquí es el Player.cpp archivo:

#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;
}

Y aquí está mi principal:

#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);
}

Hace una clase tiene que configurarse de manera diferente cuando se trata con los punteros para evitar estas violaciones de acceso? Gracias!

  • evitar escribir using namespace std .
  • excepto en los ejemplos que usted publique de desbordamiento de la pila.. entonces está bien. También, si solo lo puso en .archivos cpp, no es tan malo-nunca acaba de poner en el .h archivo de código real.
  • ¿Cuál es la razón para que el puntero de uso? Usted escribió todo, entonces, por alguna razón, se introdujo un Player * en su programa. Por qué?
  • por qué nunca se debe poner en .h archivo de código real? ¿Qué tiene de malo ?
  • Porque infecta a todos los demás .h archivos #include después de él-incluyendo cosas que se incluyen sus .h archivo y, a continuación, otras cosas. Los espacios de nombres de evitar conflictos de nombres, pero si la fuerza de su «uso» de la directiva en una librería de terceros, puede tener conflictos y dejar de compilación debido a la ambigua símbolos (std:: y en esta biblioteca) — en definitiva, acostumbrarse a escribir std:: no es tan difícil.
  • Voy a mirar eso. Gracias. La clase que estoy tomando, mi profesor, y el libro que estamos leyendo de todo un conjunto de programas de este camino. Sin duda, puedo pasar de esta práctica.

1 Comentario

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

    Que sólo los cambios de la copia local de jugador. Para cambiar el puntero fuera de la función que usted necesita para tomar una referencia para el puntero (o un doble puntero). Uso:

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

    lugar.

    • Gracias! Tengo una pregunta de seguimiento, tratando de envolver mi cabeza alrededor de esto: yo estaba bajo la impresión de que pasar un puntero a una función dirigida esa función a una dirección de memoria. Me refiero a que una copia no ser de que el parámetro argumento, pero se harán cambios directamente en el valor almacenado en esa dirección. Es el jugador se copian dentro de la función de prueba?
    • a menos que se pase por referencia, todo en C++ (y siempre todo en C) se pasa por valor, lo que hace una copia. En este caso, la copia del PUNTERO está hecho. La copia del puntero puede modificar el contenido que se señala, al igual que la original puntero, pero modificar el puntero en sí mismo es simplemente la modificación de la copia. original_ptr->some_int_field=1; y copy_of_original_ptr_in_function->some_int_field=1; ambos hacen lo mismo. original_ptr = &some_player_object; sólo afecta a original_ptr y copy_of_original_ptr_in_function = &some_player_object sólo afecta a la copia.
    • Si se le pasa un puntero a un puntero (un doble puntero), que permiten cambiar la cosa que el original puntero puntos, pero las referencias tienden a ser más fácil trabajar con y tienen la ventaja de no poder ser null – que es apropiada para su situación.

Dejar respuesta

Please enter your comment!
Please enter your name here