У меня проблемы с использованием файлового ввода-вывода для создания экземпляров моих классов для игры, над которой я работаю. Это может быть глупый вопрос, но я не могу понять, почему компилятор, кажется, успешно создает объекты из данных, хранящихся в текстовом файле, и тогда я не могу получить к ним доступ. (Я протестировал вызовы функции .display () и добавил простой cout << «Объект создан»; в конструктор, чтобы проверить, что-то было создано.)
Но код, пытающийся получить доступ к отдельным объектам, дает мне Ошибка: «идентификатор» не определен при попытке получить доступ к объектам-функциям объектов. Я, вероятно, делаю что-то совершенно не так, и я был бы признателен за толчок в правильном направлении, я пытался изменить синтаксис в цикле while для создания объекта, но я еще не взломал его. Заранее спасибо! Код ниже …
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;
};
В C ++ все ваши переменные должны быть объявлены по имени в вашем коде. Вы объявляете кучу переменных-указателей с именами line
в вашем цикле, а затем пытается использовать другие именованные переменные, такие как health
, fatigue
и т. д., которые не были созданы.
Я не думаю, что вы можете напрямую создавать переменные по имени из файла, подобного этому, но вы можете прочитать файл и создать массив или вектор объектов, которые содержат данные из файла. Вы можете передать строку, прочитанную getline()
в ваш Attributes
конструктор, а затем сохранить созданные указатели в массиве или карте, к которым вы можете обратиться позже для вызова таких методов, как display()
, Если вы действительно хотите переменную с именем health
в вашем коде это должно быть объявлено где-то в коде.
Еще один незначительный момент заключается в том, что вы повторно используете имя переменной line
(который вы ранее объявили как std :: string) в области видимости цикла. Это может работать, но сбивает с толку и его следует избегать. Вызовите указатель переменной как-нибудь еще, например attItem
,
Например:
Attributes * attItem = new Attributes(line);
attList.push_back(attItem);
Вы не отправляете какую-либо информацию, которую получили, чтобы создать новый объект. Добавить конструктор, который принимает строку с информацией, а затем инициализировать Attributes
вот так:
Atrributes::Attributes(String data){
//parse string and initialize data here
}
Кроме того, я бы порекомендовал не делать ваши Attributes
Объект имеет то же имя, что и переменная, которая содержит данные. Даже если он безвреден (и я не уверен, что это так), он просто не очень чистый.
C и C ++ не позволяют создавать новые имена переменных во время выполнения. таким образом health
в health.display();
не может прийти от чтения файла.
Что вы можете сделать, это иметь коллекцию Attributes
(например. attList
) и функция, которая находит подходящий для вас атрибут:
Attribute health = attList.find("health");
(Или если вы предпочитаете использовать map
Вы могли бы сделать:
Attribute health = attList["health"];
Другой подход, конечно, заключается в том, чтобы атрибуты сохранялись в каждом объекте, например
class PlayerBase
{
private:
Attribute health;
Attribute speed;
...
public:
void SetAttribute(const string& name, const Attribute& attr);
};
Тогда вы найдете правильный атрибут, сравнивая string name
:
void SetAttribute(const string& name, const Attribute& attr)
{
if (name == "health") health = attr;
if (name == "speed") speed = attr;
...
}