封装和友类

encapsulation and friend classes in C++

本文关键字:封装      更新时间:2023-10-16

我正在学习c++容器和迭代器,我正在尝试实现一个基本的链表,只是为了掌握迭代器和容器相关的内部工作原理。

我定义了一个节点类,以及一个列表类和相关的迭代器,每个类都在自己的头文件中,每个头文件都在单独的代码文件中实现。我不关心朋友声明,这是我打算在编译项目时迎合的东西,但是我偶然发现了一些我无法理解的东西。

我在每个类中定义了几个私有字段,我期望编译器在编译期间向我抛出一些错误,但它似乎很好!你能解释一下我错在哪里吗?下面是代码:

节点类:

template <typename T>
class mylist_node {
  public:  
    mylist_node(const T&,mylist_node<T>*);
    ~mylist_node() {}
  private:
    T element;
    mylist_node<T> *next;
};

list类:

template <typename T>
class mylist {
  public:
    typedef mylist_iterator<T> iterator;
    mylist() : head(NULL),tail(NULL) {}
    void push_back(const T&);
    bool empty();
    iterator begin();
    iterator end();
  private:
    mylist_node<T> *head,*tail;
};

列表实现代码:

#include <cstdlib>
#include "mylist_node.h"
#include "mylist_iterator.h"
#include "mylist.h"
template <typename T>
void mylist<T>::push_back(const T& element)
{
  //dynamically allocated object so it is not destroyed on function exit
  mylist_node<T> *new_node=new mylist_node<T>(element,NULL);  
  if (head==NULL)                   
    head=new_node;
  else
    tail->next=new_node;
  tail=new_node;      
}
template <typename T>
bool mylist<T>::empty()
{
  return head==tail;
}
template <typename T>
typename mylist<T>::iterator mylist<T>::begin()
{
  return mylist_iterator<T>(head);
}
template <typename T>
typename mylist<T>::iterator mylist<T>::end()
{
  return mylist_iterator<T>(NULL);
}

和迭代器类:

template <typename T>
class mylist_iterator {
  public:
    T &operator*();
    const mylist_iterator<T> &operator++();
    bool operator!=(const mylist_iterator<T>&);
  private:
    mylist_iterator(mylist_node<T> *pointee) : pointee(pointee) {}
    mylist_node<T> *pointee;
};

显然,mylist<T>::push_back()mylist_iterator中的重载操作符都访问了mylist_node中的私有字段。我分别编译源文件,而编译器根本没有抱怨任何事情!

一定有什么地方我没有完全理解……

谢谢!

编译器通常没有一种方法来"排序"编译代码,以找出无论类型如何都会发生的错误。他们需要用真正的类型编译代码来检测大多数错误。如果您从不实例化这些类中的任何一个,那么真正的编译就不会发生。