2

I am new to C++ and I'm trying to do the following:

1) I have created a class of objects called Objects which contains the name of the object and a number to identify them.

2) I have created a class Group which inherits from list, as follows:

#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) Then, I have implemented the method showlist as follows:

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";
    } }

And the method getGroupName is as follows:

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

4) In the main program I have created a pointer to a variable of type Group. The code compiles without any error, but when I executed it I realized that the program enters the method showlist and gets out without executing the for-loop. I have tested this by putting messages with printf. Just the messages "Before method", "I'm here 1", and "After method" are showed in the terminal. It doesn't show "I'm here 2". I call from main as follows:

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;

Could you please help me to understand why the loop is not being executed?


Update

The program didn't enter to the loop because the list was empty, as explained in the answers of the members.

As for this case inheriting from List is a constraint, I have filled the list in the main function as follows:

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]);

Where File is a class which inherits from the class Objects. This way the program compiles and executes. In the command line it is shown the attribute of the class Groupe, being g1. I want to use the method display which is already implemented in the class Objects but when I try to do it the compiler shows this error:

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

So, my question is how can I make the class Group to inherit the methods from both List (which is already done) and Objects?

Marco
  • 391
  • 4
  • 18
  • 4
    Put a break point in your code and step through it to see if it is really skipping the loop or what else could be happening. – Jacobr365 Feb 23 '16 at 15:20
  • 8
    You don't want to inherit from standard containers. Use aggregation instead of inheritance. – crashmstr Feb 23 '16 at 15:21
  • To answer your question after your update, check [multiple inheritance](http://www.learncpp.com/cpp-tutorial/117-multiple-inheritance/) – Nacho Feb 24 '16 at 02:25

3 Answers3

6

Because you are not putting anything into your list. You are creating five empty, unrelated lists in an array, and then stepping through the (empty) first group.

H. Guijt
  • 3,325
  • 11
  • 16
3

Disregarding for the moment that you should not derive from the standard library containers (see Is there any real risk to deriving from the C++ STL containers?) ...

The line

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

allocates memory for 5 Group objects and assigns that memory to lgroup. However, lgroup still has no items contained in it as a list. As a result, lgroup->begin() equals lgroup->end().

If you want the other Groups to be contained in lgroup, you need to use:

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"));

For that to work, you need to make Group a sub-type of Object. It will be better to change your class to:

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_;
};

and then use

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"));
Community
  • 1
  • 1
R Sahu
  • 204,454
  • 14
  • 159
  • 270
  • Hi R Sahu, why it is not a good practice to derive from standard library containers? I have tried your suggestion but now I have compiling errors. I have the following: main.cpp:73: error: no matching function for call to 'Group::push_back(Group*)' lgroup->push_back(new Group("g2")); ^ – Marco Feb 23 '16 at 15:40
  • @MarcoSurca, that's right. `Group` is derived from `Object`. Hence, a `Group*` cannot cast to an `Object*`. – R Sahu Feb 23 '16 at 15:46
  • 1
    @MarcoSurca, see [Is there any real risk to deriving from the C++ STL containers?](http://stackoverflow.com/questions/922248/is-there-any-real-risk-to-deriving-from-the-c-stl-containers) – R Sahu Feb 23 '16 at 15:51
  • thanks, I have understood why it is not good to inherit from STL. Nevertheless, for this case inheriting from List is a constraint. I have filled the 'List' as shown in the update of the question. But I would like to know if it is possible to inherit methods from both 'List' and 'Objects'. When I call a method already implemented in 'Objects' the program doesn't compile. – Marco Feb 24 '16 at 00:47
  • @MarcoSurca, yes, it is possible to derive from multiple objects. Give it a shot. – R Sahu Feb 24 '16 at 04:25
0

For the first question, the program didn't enter to the loop because the list was empty, as explained in the answers of the members.

For the second question, it was not necessary to use multiple inheritance to inherit the methods from the class Object. For this case, display is the method I want to use. It is necessary to call it with a pointer:

    for(list<Object*>::const_iterator it = this->begin(); it != this->end(); it++){
        sl << this->getGroupName() << ' ' ;
             (*it)->display(sl);
Marco
  • 391
  • 4
  • 18