关于封装的C ++迭代节点

时间:2018-10-19 07:41:13

标签: c++

我正在编写一个函数,该函数从基于LinkedList / Node数据结构运行的队列类中迭代Queue。

我已经能够使函数起作用,但是只能通过直接从LinkedList类获取指向头节点的指针,据我所知,该类被认为是不好的封装。

这是我的代码:

main():

    int main()
    {
        Queue list;
        int nums[] = {60, 50, 40};
        for (int i=0; i<(int)sizeof(nums)/(int)sizeof(nums[0]); i++) {list.enqueue(nums[i]);}
        list.iterate();
    }

队列:

.h

#include "LinkedList.h"
class Queue
{
    public:
    typedef int value_type;
    Queue();
    void enqueue(value_type& obj);
    int size() const;
    void iterate();
    int min();
    private:
    LinkedList data;
    int used;
};
#include "Queue.hpp"

.hpp

Queue::Queue()
{ data = LinkedList(); used = 0; }
void Queue::enqueue(value_type& obj)
{ ++used; data.addToTail(obj); }
int Queue::size() const
{ return used; }
void Queue::iterate()
{
    node * temp = data.get_head();
    for (int i = 0; i < size(); i++)
    { cout << temp->get_data() << endl; temp = temp->get_next(); }
    delete temp;
}

LinkedList

.h

#include "Node.h"
class LinkedList
{
    public:
    typedef int value_type;
    LinkedList();
    void addToHead(typename node::value_type& entry);
    void addToTail(typename node::value_type& entry);
    node * get_head();
    int front();
    private:
    node* head;
    node* tail;
    node* current;
};
#include "LinkedList.hpp"

.hpp

LinkedList::LinkedList()
{ head = NULL; tail = NULL; current = NULL; }

void LinkedList::addToTail(value_type& entry)
{
    if (get_head() == NULL)
    { addToHead(entry); }
    else {
        node* add_ptr = new node;
        add_ptr->set_data(entry);
        add_ptr->set_next(current->get_next());
        add_ptr->set_previous(current);
        current->set_next(add_ptr);
        if (current == tail) {tail = current->get_next();}
        current = current->get_next();
    }
}

void LinkedList::addToHead(value_type& entry)
{ head = new node(entry, head); if (tail == NULL) {tail = head;} current = head; }

node * LinkedList::get_head()
{ return head; }

int LinkedList::front()
{ int rval = head->get_data();return rval; }

节点

.h

class node
{
    public:
    typedef int value_type;
    node();
    node(const value_type& data, node* link);
    void set_data(const value_type& new_data);
    void set_next(node* next_ptr);
    void set_previous(node* last_ptr);
    int get_data() const;
    node* get_next() const;
    node* get_previous() const;
    private:
    value_type data;
    node* next;
    node* previous;
};
#include "Node.hpp"

.hpp

node::node()
{ data = 0; next = 0; previous = 0; }
node::node(const value_type& data, node* link)
{ this->data = data; this->next = link; this->previous = NULL; }
void node::set_data(const value_type& new_data) {data = new_data;}
void node::set_next(node* next_ptr) {next = next_ptr;}
void node::set_previous(node* last_ptr) {previous = last_ptr;}
int node::get_data() const {return data;}
node* node::get_next() const {return next;}
node* node::get_previous() const {return previous;}

是否可以在不直接检索指针节点的情况下迭代LinkedList?这是不好的做法吗?

2 个答案:

答案 0 :(得分:2)

您不会在Queue类的接口(即头文件中)内公开链表的(内部)数据结构。您只是在实现中使用这些数据结构。因此,我想说您不会“违反封装”。

但是,当然,您可以调整LinkedList的接口,以使其不直接使用内部数据结构。标准库及其迭代器显示了如何实现这种概念。迭代器是一个对象,它表示元素在容器中的位置(并提供对相应元素的访问)。

答案 1 :(得分:2)

没有违反Queue中的封装,但是在LinkedList中,您不应该具有返回私有指针成员的get_head()函数(如果有人这样做,该怎么办:list.get_head()-> set_next(空值))。您需要在LinkedList中创建一个迭代函数,然后Queue :: iterate只会调用此函数。