سؤال

واني اسعى الى تجميع هذه قطعة بسيطة جدا من التعليمات البرمجية

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

وماذا يمكنني أن أفعل لجعل هذا العمل دون خلق المزيد من الأشياء التي تحتاج أو overcomplicating الاشياء ...

هل كانت مفيدة؟

المحلول

واضافة بضع الصانعين ومؤشر إلى فئة الأصل.

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

وتحتاج منشئ قائمتي ()، لذلك تسجل حالات نفسها مع مثيل متغير عضو الفئة الداخلي. ثم كنت في حاجة إلى منشئ عناصر لتخزين المؤشر إلى مثيل فئة قائمتي الخارجي. وأخيرا في طريقة إضافة، تحتاج إلى مرجع مركزنا في المقام قائمتي المخزنة.

وكما يشير Catskul بها، منشئ مادة ينبغي في الواقع لا تفعل أي شيء مع قائمتي مؤشر تتلقاها. أود أن أقول أيضا أنه على الرغم من هذا الجواب هو أقرب إلى القصد الأصلي، والإجابة steveth45 هي أقرب إلى ما كنت تريد أن تفعل في برنامج حقيقي.

نصائح أخرى

وهذه الطريقة التي لا يتم تعريض أعضاء الفئة الخاصة بك مباشرة. يبدو المثال الخاص بك الإفراط في هندستها قليلا. لماذا وضعت الأمراض المنقولة جنسيا :: ناقلات في فئة ومن ثم تعريضها كما الجمهور؟

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

وعلى عكس جافا، وكائنات الداخلية في C ++ لا يستطيعون الوصول إلى "هذا" المؤشر الخارجي ... إذا كنت تفكر في ذلك قد تكون هناك حالات حيث لا يوجد احد لمرجعية.

وحل ريتشارد المراوغة هو أقرب يمكنك الحصول في C ++

و

والطبقات الداخلية تتعلق فقط بالاسم. لا يمكنك الرجوع إلى ناقلات في الفئة الأساسية من هذا القبيل.

وتحتاج إما إلى نقل متجه إلى الطبقة الداخلية أو تخزين إشارة إلى ذلك.

ولئن كان هذا المنصب هو بضع سنوات من العمر I <م> قد تكون قادرا على إضافة شيء مفيد له. حين أقول أن تصميم الفئة في آخر الأصلي لا تبدو كبيرة، وهناك أوقات حيث انها مفيدة لديها فئة جزءا لا يتجزأ من أن تكون قادرة على الوصول إلى الطبقة التي تحتوي على. يمكن بسهولة أن يتم ذلك دون تخزين مؤشرات إضافية. وفيما يلي مثال على ذلك. يجب أن تعمل كما نزعتها من بعض التعليمات البرمجية الموجودة وتغيير بعض أسماء حولها. والمفتاح هو الماكرو EmbeddorOf. تعمل مثل السحر.

و////////////////////. ح ملف //////////////////////// /

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 /////////////////

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

ونيك

ويمكنك تبسيط ذلك من خلال التركيبة التالي:

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

وحقا لماذا لا يتم استخدام ناقلات STL مباشرة؟ وبهذه الطريقة يمكنك الحصول على جميع خوارزميات قياسية تعمل مع البيانات.

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top