Я новичок в C ++ и пытаюсь сделать следующее:

1) Я создал класс объектов под названием Objects, который содержит имя объекта и номер для их идентификации.

2) Я создал группу классов, которая наследуется от списка следующим образом:

#include "objects.h"
#include <list>
#include <iostream>
#include <string> using namespace std;

class Group : public std::list<Objects*> { private:
    string groupname;

public:
    Group(string groupname);
    virtual ~Group() {} //destructor

    virtual string getGroupName() const;
    virtual void showlist(ostream & sl) const; };

3) Затем я реализовал метод showlist следующим образом:

void Groupe::showlist(ostream & sl) const{
        printf("I'm here 1\n");

        for(auto it = this->begin(); it != this->end(); it++){
             printf("I'm here 2\n");

             sl << this->getGroupName() << "test" << "test\n" << endl;
             std::cout << "I'm alive";
    } }

А метод getGroupName выглядит следующим образом:

string Group::getGroupName() const{
    return groupname;
}    

4) В основной программе я создал указатель на переменную типа Group. Код компилируется без ошибок, но когда я его выполнил, я понял, что программа входит в список методов и выходит, не выполняя цикл for. Я проверил это, поместив сообщения с помощью printf. В терминале отображаются только сообщения «До метода», «Я здесь 1» и «После метода». Это не показывает "Я здесь 2". Звоню из главной следующим образом:

Group *lgroup = new Group[5] {Group("g1"), Group("g2"),Group("g3"),Group("g4"),Group("g5")};

    printf("Before method\n");
    lgroup->showlist(sl);
    printf("After method\n");
    cout << sl.str() << endl;

Не могли бы вы помочь мне понять, почему цикл не выполняется?


Обновить

Программа не вошла в цикл, потому что список был пуст, как объяснено в ответах участников.

Поскольку в этом случае наследование от List является ограничением, я заполнил список в основной функции следующим образом:

Groupe *lgroup1 = new Groupe("g1");
Object *objets[3];

objets[1] = new File("/home/Documents", "b2.jpg",0,0);
objets[2] = new File("/home/Documents", "b3.jpg",0,0);
objets[3] = new File("/home/Documents", "b4.jpg",0,0);

lgroup1->push_back(objets[1]);
lgroup1->push_back(objets[2]);
lgroup1->push_back(objets[3]);

Где File - это класс, наследующий от класса Objects. Таким образом программа компилируется и запускается. В командной строке отображается атрибут класса Groupe, являющийся g1. Я хочу использовать метод display, который уже реализован в классе Objects, но когда я пытаюсь это сделать, компилятор показывает эту ошибку:

 error: 'const class Group' has no member named 'display'
              sl << this->display(cout) << '\n' << endl;

Итак, мой вопрос: как я могу заставить класс Group наследовать методы как от List (что уже сделано), так и от Objects?

2
Marco 23 Фев 2016 в 18:17

3 ответа

Лучший ответ

Не обращая внимания на то, что вы не должны выводить из контейнеров стандартной библиотеки (см. Есть ли реальный риск наследования из контейнеров C ++ STL? ) ...

Линия

Group *lgroup = new Group[5] {Group("g1"), Group("g2"),Group("g3"),Group("g4"),Group("g5")};

Выделяет память для 5 объектов группы и назначает эту память для lgroup. Однако lgroup по-прежнему не содержит элементов в виде списка. В результате lgroup->begin() равно lgroup->end().

Если вы хотите, чтобы другие Group содержались в lgroup, вам необходимо использовать:

Group *lgroup = new Group;
lgroup->push_back(new Group("g1"));
lgroup->push_back(new Group("g2"));
lgroup->push_back(new Group("g3"));
lgroup->push_back(new Group("g4"));
lgroup->push_back(new Group("g4"));

Чтобы это работало, вам нужно сделать Group подтипом Object. Лучше изменить свой класс на:

class Group : public Object
{
   private:
      string groupname;

   public:
      Group(string groupname);
      virtual ~Group() {}

      std::list<Objects*>& getObjects();
      std::list<Objects*> const& getObjects() const;

      virtual string getGroupName() const;
      virtual void showlist(ostream & sl) const; 
      std::list<Objects*> objects_;
};

А затем используйте

Group *lgroup = new Group;
lgroup->getObjects().push_back(new Group("g1"));
lgroup->getObjects().push_back(new Group("g2"));
lgroup->getObjects().push_back(new Group("g3"));
lgroup->getObjects().push_back(new Group("g4"));
lgroup->getObjects().push_back(new Group("g4"));
3
Community 23 Май 2017 в 12:15

По первому вопросу программа не вошла в цикл, потому что список был пуст, как объяснено в ответах участников.

Что касается второго вопроса, не было необходимости использовать множественное наследование для наследования методов от класса Object. В этом случае я хочу использовать display. Вызвать его нужно указателем:

    for(list<Object*>::const_iterator it = this->begin(); it != this->end(); it++){
        sl << this->getGroupName() << ' ' ;
             (*it)->display(sl);
0
Marco 25 Фев 2016 в 18:45

Потому что вы ничего не вносите в свой список. Вы создаете пять пустых несвязанных списков в массиве, а затем проходите через (пустую) первую группу.

6
H. Guijt 23 Фев 2016 в 15:24