【问题标题】:encapsulation and friend classes in C++C++ 中的封装和友元类
【发布时间】:2015-11-19 01:59:52
【问题描述】:

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

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

我在每个类中定义了几个私有字段,并且我希望编译器在编译过程中会向我抛出一些错误,但这似乎很好!你能解释我哪里错了吗?这是代码:

节点类:

template <typename T>
class mylist_node {

  public:  
    mylist_node(const T&,mylist_node<T>*);
    ~mylist_node() {}

  private:
    T element;
    mylist_node<T> *next;
};

列表类:

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&lt;T&gt;::push_back()mylist_iterator 中的重载运算符都访问mylist_node 中的私有字段。 我单独编译源文件,编译器完全没有抱怨!

一定有什么我没完全理解的东西..

谢谢!

【问题讨论】:

  • 如果您投反对票,您能解释一下原因吗?谢谢
  • 你没有问问题。你期望编译器抱怨吗?如果是这样,为什么?如果您不解释您的误解,我们无法纠正您的误解。
  • 实际上,我预计编译会失败,因为您为模板类which one usually don't do 使用单独的头文件和源文件。再加上您的困惑,让我相信您实际上并未使用所有源文件进行构建。
  • 你可能永远不会实例化这些类中的任何一个。
  • @JoachimPileborg 所以如果我重写代码并将所有实现内联在类定义中,它应该实例化模板并找到 push_back() 的匹配项,因此抱怨类访问?

标签: c++ templates encapsulation friend


【解决方案1】:

编译器通常没有办法“某种”地编译代码来找出无论类型如何都会发生的错误。他们需要使用真实类型实际编译代码以检测大多数错误。如果您从不实例化这些类中的任何一个,则不会进行真正的编译。

【讨论】:

  • 但是你也需要调用/实例化特定的成员函数,对吧?
猜你喜欢
  • 1970-01-01
  • 2014-08-27
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-02-13
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多