tags:

views:

3840

answers:

5

i am trying to compile this very simple piece of code

class myList
{
public:
    std::vector<std::string> vec;
    class Items
    {
    public:
     void Add(std::string str)
     {
      myList::vec.push_back(str);
     };
    }items;
};

int main()
{
    myList newList;
    newList.items.Add("A");
}

what can i do to make this work without creating more objects that needed or overcomplicating stuff...

+10  A: 

Add a couple of constructors and a pointer to the parent class.

#include <string>
#include <vector>
class myList
{
public:
    std::vector<std::string> vec;
    myList(): items(this) {} // Added
    class Items
    {
    public:
        Items(myList *ml): self(ml) {}  // Added
        void Add(std::string str)
        {
                self->vec.push_back(str); // Changed
        };
        myList *self; //Added
    }items;
};

int main()
{
    myList newList;
    newList.items.Add("A");
}

You need the myList() constructor, so it registers instances of itself with the instance of the inner class member variable. Then you need the Items constructor to store the pointer to the outer myList class instance. Finally in the Add method, you need to reference vec in the stored myList instance.

As Catskul points out, the Item constructor mustn't actually do anything with the myList pointer it receives. I'd also like to say that though this answer is closer to the original intent, steveth45's answer is closer to what you would want to do in a real program.

rq
thanks very much, this works, but i was hoping that a simpler version existed, but i must continue to cope with C++ stuborness :-( hope C++0x solves some of those quirks
... but be careful with passing the MyList this pointer while MyList is still being constructed. The Items constructor can get itself in trouble if it does anything that ends up using the MyList this pointer too early.
Catskul
+11  A: 

This way you aren't exposing your class members directly. Your example seems over-architected a bit. Why put a std::vector into a class and then expose it as public?

class myList
{
private:
    std::vector<std::string> vec;
public:
    void Add(std::string str)
    {
        vec.push_back(str);
    };
};

int main()
{
    myList newList;
    newList.Add("A");
}
postfuturist
The original author probably needs the inner class construct for other stuff he's not mentioning (for simplicity of his exposition). You're right about the software engineering soft aspect given existing information but the problem seems like a "toy" abstracting compilation problems for could originally have been a quite complex algorithm. It's not important really, you probably understand already, I'm just saying...
Joe Soul-bringer
+2  A: 

Inner classes are only related by name. You can't refer to the vector in the base class like that.

You either need to move the vector in to the inner class or store a reference to it.

Dave Hillier
+4  A: 

Unlike Java, inner objects in C++ don't have access to an outer 'this' pointer ... if you think about it there may be cases where there isn't one to reference.

Richard Quirk's solution is the nearest you can get in C++

Rob Walker
A: 

You can simplify this by the following construct:

typedef std::vector<std::string> myList;

Really why don't you use the STL vector directly? This way you get all the standard algorithms work with the data.

phoku