如何调用传递定义为protected的类的对象的方法

时间:2010-12-23 22:06:38

标签: c++ class protected

我已经考虑了好几个小时,但仍然无法理解......这是链接列表的开源定义。

template <typename T> 
class NPT_List 
{
protected:
    class Item;

public:
    // types
    typedef T Element;

    class Iterator {
    public:
        Iterator() : m_Item(NULL) {}
        explicit Iterator(Item* item) : m_Item(item) {}
        Iterator(const Iterator& copy) : m_Item(copy.m_Item) {}
        T&  operator*()  const { return m_Item->m_Data; }
        T*  operator->() const { return &m_Item->m_Data;}
        Iterator& operator++()  { // prefix
            m_Item = m_Item->m_Next;
            return (*this); 
        }
        Iterator operator++(int) { // postfix
            Iterator saved_this = *this;
            m_Item = m_Item->m_Next;
            return saved_this;
        }
        Iterator& operator--() { // prefix
            m_Item = m_Item->m_Prev;
            return (*this); 
        }
        Iterator operator--(int) { // postfix
            Iterator saved_this = *this;
            m_Item = m_Item->m_Prev;
            return saved_this;
        }
        operator bool() const {
            return m_Item != NULL;
        }
        bool operator==(const Iterator& other) const {
            return m_Item == other.m_Item;
        }
        bool operator!=(const Iterator& other) const {
            return m_Item != other.m_Item;
        }
        void operator=(const Iterator& other) {
            m_Item = other.m_Item;
        }
        void operator=(Item* item) {
            m_Item = item;
        }

    private:
        Item* m_Item;

        // friends
        friend class NPT_List<T>;
    };

    // methods
                 NPT_List<T>();
                 NPT_List<T>(const NPT_List<T>& list);
                ~NPT_List<T>();
    NPT_Result   Add(const T& data);
    NPT_Result   Insert(const Iterator where, const T& data);
    NPT_Result   Remove(const T& data, bool all=false);
    NPT_Result   Erase(const Iterator position);
    NPT_Result   PopHead(T& data);
    bool         Contains(const T& data) const;
    NPT_Result   Clear();
    NPT_Result   Get(NPT_Ordinal index, T& data) const;
    NPT_Result   Get(NPT_Ordinal index, T*& data) const;
    NPT_Cardinal GetItemCount() const { return m_ItemCount; }
    Iterator     GetFirstItem() const { return Iterator(m_Head); }
    Iterator     GetLastItem() const  { return Iterator(m_Tail); }
    Iterator     GetItem(NPT_Ordinal index) const;

    // list manipulation
    NPT_Result   Add(NPT_List<T>& list);
    NPT_Result   Remove(const NPT_List<T>& list, bool all=false);

    // item manipulation
    NPT_Result   Add(Item& item);
    NPT_Result   Detach(Item& item);
    NPT_Result   Insert(const Iterator where, Item& item);

    // list operations
    // keep these template members defined here because MSV6 does not let
    // us define them later
    template <typename X> 
    NPT_Result Apply(const X& function) const
    {                          
        Item* item = m_Head;
        while (item) {
            function(item->m_Data);
            item = item->m_Next;
        }

        return NPT_SUCCESS;
    }

    template <typename X, typename P> 
    NPT_Result ApplyUntil(const X& function, const P& predicate, bool* match = NULL) const
    {                          
        Item* item = m_Head;
        while (item) {
            NPT_Result return_value;
            if (predicate(function(item->m_Data), return_value)) {
                if (match) *match = true;
                return return_value;
            }
            item = item->m_Next;
        }

        if (match) *match = false;
        return NPT_SUCCESS;
    }

    template <typename P> 
    Iterator Find(const P& predicate, NPT_Ordinal n=0) const
    {
        Item* item = m_Head;
        while (item) {
            if (predicate(item->m_Data)) {
                if (n == 0) {
                    return Iterator(item);
                }
                --n;
            }
            item = item->m_Next;
        }

        return Iterator(NULL);
    }

    // operators
    void operator=(const NPT_List<T>& other);
    bool operator==(const NPT_List<T>& other) const;
    bool operator!=(const NPT_List<T>& other) const;

protected:
    // types
    class Item 
    {
    public:
        // methods
        Item(const T& data) : m_Next(0), m_Prev(0), m_Data(data) {}

        // members
        Item* m_Next;
        Item* m_Prev;
        T     m_Data;

        // friends
        //friend class NPT_List<T>;
        //friend class NPT_List<T>::Iterator;
    };

    // members
    NPT_Cardinal m_ItemCount;
    Item*        m_Head;
    Item*        m_Tail;
};

我需要调用方法Detach以避免在列表超出范围时释放此列表的元素(我看到析构函数删除了所有元素)。 我的问题是:我该如何调用它?我无法创建Item的实例,因为类Item受到保护。那么,这个列表应该如何工作呢? 如果有必要,我当然可以修改列表,但我真的很感兴趣它应该如何工作,因为我正在尝试学习C ++,所以我想理解。

非常感谢您的帮助!

4 个答案:

答案 0 :(得分:2)

这门课是胡说八道。您注意到自己没有看到如何拨打Detach(),实际上我也看不到您如何拨打Detach()。另外,一方面,protected中有NPT_List个成员,但另一方面,该类有一个非虚拟析构函数。这些是混合信息。和一个有这种特质的女孩(或者一个男人;检查什么适合你)一样,你应该远离它。

答案 1 :(得分:0)

你不能只从NPT_List继承,然后将Item推广到公众吗?

class FooList : public NPT_List<Foo>
{
  public:
    class Item;

  ...
} 

答案 2 :(得分:0)

该类的接口不正确。 AddDetachInsert应采用T&参数,而不是Item&Detach还需要一个迭代器参数来指示要分离的元素。

修改:正如其他人所指出的,已有AddInsert方法采用const T&参数,因此这些其他方法可能都是为了受到保护。一个小错误。绊倒你的是缺少使用Detach的{​​{1}}方法。它需要作为一种新方法添加:

T&

答案 3 :(得分:0)

使用Item类型的方法是不应该成为公共接口一部分的实用方法。请改用Iterator版本来访问相同的功能:

NPT_Result   Add(const T& data);
NPT_Result   Insert(const Iterator where, const T& data);
NPT_Result   Erase(const Iterator position);