Question

I am having trouble using file I/O to create instances of my classes for a game I am working on. It might well be a dumb question, but I cannot fathom out why the compiler seems to successfully creates the objects from the data stored in the text file and then I can't access them. (I took out the .display() function calls to test this, and added a simple cout << "Object created"; into the constructor to check something had been created.)

But the code trying to access the individual objects gives me Error: "identifier" is undefined when trying to access the objects member functions. I am probably doing something completely wrong and I would appreciate a push in the right direction, I have tried changing the syntax in the while loop for creating the object, but I haven't cracked it yet. Thank you in advance! Code below...

main.cpp

#include <iostream>
#include <string>
#include <fstream>

#include "Attributes.h"

using std::cout;
using std::endl;
using std::cin;
using std::ofstream;
using std::ifstream;
using std::getline;
using std::cerr;


int main() {

    std::string line;
    ifstream attdata;
    attdata.open("data.txt");
    if (attdata.is_open())
    {
        while (attdata.good())
        {
            getline (attdata, line);
            Attributes * line = new Attributes;
        }
        attdata.close();
    }
    else cerr << "Unable to open file.";

health.display();
fatigue.display();
attack.display();
skill.display();
defence.display();
skilldef.display();
speed.display();
luck.display();
};

data.txt

health
fatigue
attack
skill
defence
skilldef
speed
luck

Atributes.h

#pragma once
#include <string>

class Attributes
{
public:
    Attributes(void);
    Attributes(std::string name, std::string shortName, std::string desc, int min, int max);
    ~Attributes(void);
    void display();
private:
    std::string m_nameLong;
    std::string m_nameShort;
    std::string m_desc;
    int m_minValue;
    int m_maxValue;

};
Était-ce utile?

La solution

In C++, all your variables need to be declared by name in your code. You are declaring a bunch of pointer variables all named line in your loop, and then trying to use other named variables like health, fatigue, etc that have not been created.

I don't think you can directly create variables by name from a file like this, but you could read the file and create an array or vector of objects that contain the data from the file. You could pass the string read by getline() into your Attributes constructor, and then store the created pointers in an array or map that you can access later to call methods like display(). If you really want a variable called health in your code, it has to be declared somewhere in the code.

Another minor point is that you are reusing the variable name line (which you previously declared to be a std::string) in the loop scope. This may work, but is confusing and should be avoided. Call your pointer variable something else, like attItem.

For example:

Attributes * attItem = new Attributes(line);
attList.push_back(attItem);

Autres conseils

You arent sending any of the information that you received to create the new object. Add a constructor that takes in a string with the information and then initialize Attributes like so:

Atrributes::Attributes(String data){
  //parse string and initialize data here
}

Also, I would recommend not making your Attributes object have the same name as the variable that holds the data. Even if it's harmless (and im not sure that it is), its just not very clean.

C and C++ doesn't allow new names of variables to be created at runtime. Thus health in health.display(); can not come from reading a file.

What you can do is have a collection of Attributes (e.g. attList) and a function that finds the appropriate attribute for you:

Attribute health = attList.find("health"); 

(Or if you prefer to use a map, you could do:

Attribute health = attList["health"]; 

Another approach of course is to have attributes stored in each object, e.g.

class PlayerBase
{
  private:
    Attribute health;
    Attribute speed;
    ...
  public:
    void SetAttribute(const string& name, const Attribute& attr);
}; 

Then you'd find the right attribute by comparing string name:

void SetAttribute(const string& name, const Attribute& attr)
{
   if (name == "health") health = attr;
   if (name == "speed") speed = attr;
   ...
}
Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top