Frage

Ich versuche, dieses sehr einfaches Stück Code zu kompilieren

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

Was kann ich tun, um diese Arbeit zu machen, ohne weitere Objekte zu erstellen, die Sachen benötigt oder overcomplicating ...

War es hilfreich?

Lösung

Fügen Sie ein paar Konstrukteure und einen Zeiger auf die übergeordnete Klasse.

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

Sie müssen die myList () Konstruktor, so registriert er Instanzen von sich selbst mit der Instanz der inneren Klasse Membervariable. Dann müssen Sie den Artikel Konstruktor den Zeiger auf die äußere myList Klasseninstanz zu speichern. Schließlich in der Add-Methode, müssen Sie vec in der gespeicherten myList Instanz verweisen.

Wie Catskul weist darauf hin, muss der Artikel-Konstruktor nicht tatsächlich mit dem myList alles tun, Zeiger sie empfängt. Ich möchte auch sagen, dass obwohl diese Antwort näher an der ursprünglichen Absicht ist, steveth45 Antwort ist näher an, was Sie wollen, würde in einem realen Programm zu tun.

Andere Tipps

So können Sie nicht Ihre Klasse Belichtung werden die Mitglieder direkt. Ihr Beispiel scheint ein wenig über architected. Warum ein std :: vector in eine Klasse setzen und dann als öffentlich entlarven?

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

Im Gegensatz zu Java, inneren Objekte in C ++ haben keinen Zugang zu einem äußeren ‚this‘ Zeigern ... wenn man darüber nachdenkt, kann es Fälle geben, in denen es nicht einen zu Referenz.

Richard Quirk-Lösung ist der nächste Sie in C ++ bekommen

Innere Klassen sind nur der Name verwendet. Sie können nicht auf den Vektor in der Basisklasse wie das beziehen.

Sie müssen entweder den Vektor in der inneren Klasse oder speichern Sie einen Verweis auf sie bewegen.

Während dieser Beitrag ein paar Jahre alt ist I könnte der Lage sein, etwas Nützliches, um es hinzuzufügen. Während ich werde sagen, dass das Design der Klasse in der ursprünglichen Nachricht nicht so toll aussieht, gibt es Zeiten, in denen es sinnvoll ist, eine eingebettete Klasse haben kann, die enthält Klasse zuzugreifen. Dies kann leicht, ohne zu speichern zusätzliche Zeiger erfolgen. Unten ist ein Beispiel. Es sollte funktionieren, wie ich es von einem vorhandenen Code nahm und einige Namen geändert um. Der Schlüssel ist die EmbeddorOf Makro. Funktioniert wie ein Zauber.

//////////////////// .h-Datei //////////////////////// /

struct IReferenceCounted
{
    virtual unsigned long AddRef() = 0;
    virtual unsigned long Release() = 0;
};

struct IFoo : public IReferenceCounted
{
};

class Foo : public IFoo
{
public:
    static IFoo* Create();
    static IFoo* Create(IReferenceCounted* outer, IReferenceCounted** inner);

private:
    Foo();
    Foo(IReferenceCounted* outer);
    ~Foo();

    // IReferenceCounted

    unsigned long AddRef();
    unsigned long Release();

private:
    struct EIReferenceCounted : IReferenceCounted
    {
        // IReferenceCounted

        unsigned long AddRef();
        unsigned long Release();
    } _inner;

    unsigned long _refs;
    IReferenceCounted* _outer;
};

//////////////// CPP-Datei /////////////////

#include <stdio.h>
#include <stddef.h>
#include "Foo.h"

#define EmbeddorOf(class, member, this) \
    (class *) ((char *) this - offsetof(class, member))

// Foo

Foo::Foo() : _refs(1), _outer(&this->_inner)
{
}

Foo::Foo(IReferenceCounted* outer) : _refs(1), _outer(outer)
{
}

Foo::~Foo()
{
    printf("Foo::~Foo()\n");
}

IFoo* Foo::Create()
{
    return new Foo();
}

IFoo* Foo::Create(IReferenceCounted* outer, IReferenceCounted** inner)
{
    Foo* foo = new Foo(outer);
    *inner = &foo->_inner;
    return (IFoo*) foo;
}

// IReferenceCounted

unsigned long Foo::AddRef()
{
    printf("Foo::AddRef()\n");
    return this->_outer->AddRef();
}

unsigned long Foo::Release()
{
    printf("Foo::Release()\n");
    return this->_outer->Release();
}

// Inner IReferenceCounted

unsigned long Foo::EIReferenceCounted::AddRef()
{
    Foo* pThis = EmbeddorOf(Foo, _inner, this);
    return ++pThis->_refs;
}

unsigned long Foo::EIReferenceCounted::Release()
{
    Foo* pThis = EmbeddorOf(Foo, _inner, this);
    unsigned long refs = --pThis->_refs;
    if (refs == 0)
        {

        // Artifically increment so that we won't try to destroy multiple
        // times in the event that our destructor causes AddRef()'s or
        // Releases().

        pThis->_refs = 1;
        delete pThis;
        }
    return refs;
}

Nick

Sie können dies vereinfachen, indem das folgende Konstrukt:

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

Wirklich, warum Sie den STL-Vektor nicht direkt verwenden? Auf diese Weise können alle Standard-Algorithmen erhalten arbeiten mit der Daten.

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top