У меня есть класс, который состоит из ints и строк, но у меня также есть вектор внутри этого класса. Я должен прочитать записи из файла, а затем, после анализа каждой строки, поместить информацию в мой вектор класса. Мне нужно получить базовую информацию о пакете, такую как идентификатор и имя, а затем добавить услуги, которые предлагаются с этим пакетом, чтобы я мог получить 10 записей из одного пакета, но они различаются по типу услуг. Сейчас я пытаюсь поместить данные в каждый пакет и получить доступ к данным каждого элемента, но когда я пытаюсь получить данные из вектора внутри класса, мой скомпилированный файл вылетает. Он также печатает 1233 и foo, но не тест. Есть идеи, почему это?
int main()
{
vector<package> packs;
package pack;
pack.ID = 1233;
pack.name = "foo";
packs.push_back(pack);
pack.putData("test",12);cout << packs[0].name << endl;
cout << packs[0].ID << endl;
cout << packs[0].bservice[0].serviceID << endl; //[b]Crashes in this line[/b]
return 0;
}
Определенный класс:
class package
{
public:
class aservice
{
public:
int serviceID;
string othername;
};
int ID;
string name;
vector<aservice> bservice;
void putData(string name1, int serviceID1)
{
aservice obj;
obj.serviceID = serviceID1;
obj.othername = name1;
bservice.push_back(obj);
}
};
Здесь вы делаете копию pack
когда ты push_back
в вектор:
packs.push_back(pack);
И вот вам доступ pack
, а не копия, хранящаяся в вашем векторе
pack.putData("test",12);
Итак bservice
вектор, к которому вы пытаетесь получить доступ, фактически пуст, поэтому ваш код вылетает при попытке получить к нему доступ здесь:
cout << patients[0].bservice[0].serviceID << endl; // patients[0].bservice is empty!!!
Вы можете избежать этого, нажав после вызова putData
:
vector<package> packs;
package pack;
pack.ID = 1233;
pack.name = "foo";
pack.putData("test",12);
packs.push_back(pack);
Вы также можете избежать этого, не пытаясь получить доступ к вектору без предварительной проверки, является ли он пустым.
В идеале вы должны стремиться разрабатывать классы, которые могут быть превращены в полезное состояние, а не создавать их по умолчанию и добавлять данные шаг за шагом через установщики. Это особенно важно, если данные взаимосвязаны и класс должен поддерживать инварианты.
packs.push_back(pack);
Собирается нажать копию pack
в ваш вектор. Поэтому у вас будет два конкретных экземпляра: если вы вызовете putData для одного из них, другой не будет изменен сам!
Поэтому при написании
patients[0].bservice[0]
ваше приложение падает, потому что вы не сделали putData
внутри patients[0]
только внутри pack
— который, опять же, другой объект.
Вы должны изменить свой вектор так, чтобы он сохранял указатели на package
и нажмите адрес pack
внутри.
pack.push_back(pack);
Предполагая первый pack
на самом деле packs
это толкает копия из pack
на вектор.
pack.putData("test",12);
Это изменяет локальную переменную pack
, но не копия, которую вы нажали на вектор. Это все еще содержит пустой bservice
вектор.
cout << patients[0].bservice[0].serviceID << endl;
При условии, что patients
на самом деле packs
это ошибочно пытается прочитать из пустого bservice
вектор.
Вы либо хотите позвонить putData
до packs.push_back(pack)
или позвоните на packs.back()
а не местный pack
,
Попробуй это:
#include <vector>
#include <iostream>
using namespace std;
class package
{
public:
package(int inID, const string& inName ) : ID(inID), name(inName)
{
}
void putData(string name1, int serviceID1)
{
aservice obj;
obj.serviceID = serviceID1;
obj.othername = name1;
bservice.push_back(obj);
}
void Print() const
{
cout << ID << endl;
cout << name << endl;
vector<aservice>::const_iterator iter;
iter = bservice.begin();
for (; iter != bservice.end(); ++iter)
{
cout << iter->serviceID << " " << iter->othername << endl;
}
}
private:
class aservice
{
public:
aservice() {};
int serviceID;
string othername;
};
int ID;
string name;
vector<aservice> bservice;};
typedef vector<package> PackContainer;
typedef vector<package>::iterator PackContainerIterator;
typedef vector<package>::const_iterator PackContainerConstIterator;
void PrintAll(const PackContainer& packs)
{
PackContainerConstIterator iter = packs.begin();
for (; iter != packs.end(); ++iter)
{
iter->Print();
}
}
int main()
{
PackContainer packs;
package pack( 1233, "foo");
pack.putData("test",12);
packs.push_back(pack);
PrintAll(packs);return 0;
}