Загрузка разных объектов из файла

0

Я пытаюсь загрузить объекты A и B из файла, которые будут выглядеть примерно так:

A 3 4
B 2 4 5
B 3 5 6
A 2 3

У меня есть следующие классы: Base, A и B, подклассы Base. Каждый с оператором >> перегружен.

Проблема заключается в функции load(). Я не уверен, как создавать объекты.. Мой load() не компилируется, потому что 'pO was not declared in this scope. Как я могу это исправить? Или что было бы лучшим способом добиться этого?

Кроме того, если мне удастся заставить его работать как-нибудь, мне нужно будет удалить объекты вручную?

class Base
{
    public:
        Base() {}
        Base(int tot_) : tot(tot_) {}

        void print() const {
            std::cout << "Tot : " << tot << std::endl; 
        }

    private:
        int tot;
};

class A : public Base
{
    public:
        A() : Base(0) {}
        A(int a1, int a2) : Base(a1+a2) {}
};


class B : public Base
{
    public:
        B() : Base(1) {}
        B(int b1, int b2, int b3) : Base(b1+b2+b3){}
};

std::istream& operator>>(std::istream& in, A& a)
{ 
    int a1, a2;
    in >> a1; 
    in >> a2;

    a = A(a1,a2);

    return in;
}

std::istream& operator>>(std::istream& in, B& b)
{ 
    int b1, b2, b3;
    in >> b1; 
    in >> b2;
    in >> b3;

    b = B(b1,b2,b3);

    return in;
}

bool load(const std::string& s, std::vector<Base*>& objs)
{
    std::ifstream is(s.c_str());
    if (is.good())
    {
        std::string obj;
        while (!is.eof()) 
        {
            is >> obj;
            if (obj == "A") {
                A *pO = new A;
            }
            else (obj == "B") {
                B *pO = new B;
            }
            is >> *pO;
            objs.push_back(pO);
        }
        is.close();
        return true;
    }
    return false;
}
Теги:
pointers
inheritance
declaration

2 ответа

0
Лучший ответ

Вы должны объявить pO в области, в которой вы его используете:

        is >> obj;
        Base *pO;
        if (obj == "A") {
            A *a = new A;
            is >> *a;
            pO = a;
        }
        else { // (obj == "B")
            B *b = new B;
            is >> *b;
            pO = b;
        }
        objs.push_back(pO);
  • 1
    Я думаю, вы имели в виду Base * рО
  • 0
    Да, я пропустил декларации и подумал, что B является подклассом A.
Показать ещё 3 комментария
0

И ответ на ваш другой вопрос: "нужно было бы удалить объекты вручную" - да, объекты, выделенные new всегда должны быть удалены с delete.

Однако, поскольку вы нажимаете указатели на массив, убедитесь, что не удаляете их слишком рано, когда они все еще используются!

Поэтому одним альтернативным решением было бы не использовать указатели. Сделайте obj массив Base а не массив Base* и избегайте любого new или delete.

Редактировать:
Без указателей я бы написал что-то вроде этого:

while (!is.eof()) {
    is >> obj;
    if (obj == "A") {
        A pO; 
        is >> pO;
        objs.push_back(pO);
    }
    else if (obj == "B") {
        B pO;
        is >> pO;
        objs.push_back(pO);
    }
}

но убедитесь, что вы не наносили никаких обрезков объектов, добавляя переменные-члены к классу A или классу B!

  • 0
    Я с удовольствием это сделаю, но как это будет выглядеть в load ()? Я пошел с указателями, думая, что у меня не может быть вектора <Base>, заполненного A и B.
  • 0
    ОК, я отредактировал. Но я просто понимаю, что с массивом Base вы бы нарезали свои объекты. Поэтому, если вы планируете добавить переменные-члены в свой класс, добавьте их в базовый класс, а не в производные классы! (Или придерживайтесь указателей, но не забудьте удалить их перед удалением вектора objs .)

Ещё вопросы

Сообщество Overcoder
Наверх
Меню