1

オブジェクトの外部からリンクリストを操作したいのですが、思ったように機能しません。

これが状況です。リンクリストの先頭をマークする最初のエントリへの基本クラスのポインタを持つオブジェクトがあります。

class theObject {
public:
    theObject() : mFirstEntry(0), mLastEntry(0) {}
    ~theObject() {}

    template<class T>
    void addEntry(const std::string &blah, const std::string &blub, const T &hui)
    {
        child<T> *newEntry = new child<T>(blah, blub, hui);

        if (mFirstEntry) {
            mLastEntry->setNext(newEntry);
            mLastEntry = newEntry;
        }
        else {
            mFirstEntry = newEntry;
            mLastEntry = newEntry;
        }
    }

    base * getFirstEntry() const
    {
        return mFirstEntry;
    }

    void printEntrys() const
    {
        base *data = mFirstEntry;
        while(data) {
            std::cout << data->getBlah() << data->getBlub() << std::endl;
            data = data->getNext();
        }
    }

private:
    base *mFirstEntry;
    base *mLastEntry;
};

class base {
public:
    base() : mBlah(""), mBlub(""), mNext(0) {}

    base(const std::string &blah, const std::string &blub) : mBlah(blah), mBlub(blub), mNext(0) {}

    virtual ~base()
    {
        if (mNext) {
            delete mNext;
        }
    }

    void setNext(base *next)
    {
        mNext = next;
    }

    base * getNext() const
    {
        return mNext;
    }

    std::string getBlah() const
    {
        return mBlah;
    }

    std::string getBlub() const
    {
        return mBlub;
    }

protected:
    std::string mBlah;
    std::string mBlub;
    base *mNext;
};

リンクリストの各エントリは、テンプレートであり、基本クラスを継承する子型です。

template<class T>
class child : public base {
public:
    inline child(const std::string &blah, const std::string &blub, const T &hui, base *next = 0) : mHui(hui), base(blah, blub)
    {
        if(next) {
            mNext = next;
        }
    }

    inline child(const child &r)
    {
        *this = r;
    }

    inline const child & operator = (const child &r)
    {
        if (this == &r) return *this;

        mBlah = r.mBlah;
        mBlub = r.mBlub;
        mNext = r.mNext;
        mHui = r.mHui;

        return *this;
    }

    inline const T getData() const
    {
        return mHui;
    }

protected:
    T mHui;
};

今、私はいくつかのエントリでオブジェクトを埋めています

int main(int argc, char* argv[])
{
    theObject data;
    int a(0), b(1), c(2), d(3);
    const std::string blah("blah"), blub("blub");
    data.addEntry(blah, blub, a);
    data.addEntry(blah, blub, b);
    data.addEntry(blah, blub, c);
    data.addEntry(blah, blub, d);

    std::cout << "Original entries" << std::endl;
    data.printEntrys();

次に、リンクリストを操作したい

    base *stuff = data.getFirstEntry();
    std::cout << "Changed in stuff list" << std::endl;
    while(stuff) {
        stuff = new child<double>("noBlah", "noBlub", 3.14, stuff->getNext());
        std::cout << stuff->getBlah() << stuff->getBlub() << std::endl;
        stuff = stuff->getNext();
    }

そしてオリジナルを操作したかった...しかしそれは私がコピーだけを操作した継ぎ目

    std::cout << "linked list in data object should now be stuff list" << std::endl;
    data.printEntrys();

    return 0;
}

誰かがなぜそれが機能しないのか考えていますか?getFirstEntry()はポインタを返すので、それが指すオブジェクトを操作すると思いました。

よろしく、ベン

4

3 に答える 3

0

You get a pointer to the first element via base *stuff = data.getFirstEntry();, then point it to a new object instead with stuff = new child<double>("noBlah", "noBlub", 3.14, stuff->getNext());. In other words, you change the pointer, not the value pointed to.

I would recommend you review a tutorial on pointers. Someone once recommended this video: Binky Pointer Fun

于 2012-11-13T17:55:10.500 に答える
0

You return a pointer and change the local pointer, without changing the value the pointer points on! You should do:

*stuff = child<double>("noBlah", "noBlub", 3.14, stuff->getNext());

On this way you would actually change the object the pointer points on.

LG ntor

于 2012-11-13T17:59:35.807 に答える
0

Ok thanks to ntor i was able to sole the issue.

this is the code example (the code from the beginning is still valid)

template<class T>
child<T> * getnewEntry(const std::string &a, const std::string &b, const T &c, base *next)
{
    child<T> *nc= new child<T>(a, b, c, next);
    return nc;
}

int main(int argc, char* argv[])
{
    theObject data;
    int a(0), b(1), c(2), d(3);
    const std::string blah("blah"), blub("blub");
    data.addEntry(blah, blub, a);
    data.addEntry(blah, blub, b);
    data.addEntry(blah, blub, c);
    data.addEntry(blah, blub, d);

    base *stuff = data.getFirstEntry();
    stuff = getnewEntry("noBlah", "noBlub", 3.14, stuff->getNext());
    data.mFirstEntry->setNext(0);
    delete data.mFirstEntry;
    data.mFirstEntry = stuff;

    while (stuff->getNext()) {
        base *tmpstuff = getnewEntry("noBlah", "noBlub", 3.14, stuff->getNext()->getNext());
        stuff->getNext()->setNext(0);
        delete stuff->getNext();
        stuff->setNext(tmpstuff);
        stuff = tmpstuff;
    }

    data.mLastEntry = stuff;

    return 0;
}

This is now changing the object at a position of a linked list and updating the linked list

于 2012-11-14T10:59:22.617 に答える