【发布时间】: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<T>::push_back() 和mylist_iterator 中的重载运算符都访问mylist_node 中的私有字段。
我单独编译源文件,编译器完全没有抱怨!
一定有什么我没完全理解的东西..
谢谢!
【问题讨论】:
-
如果您投反对票,您能解释一下原因吗?谢谢
-
你没有问问题。你期望编译器抱怨吗?如果是这样,为什么?如果您不解释您的误解,我们无法纠正您的误解。
-
实际上,我预计编译会失败,因为您为模板类which one usually don't do 使用单独的头文件和源文件。再加上您的困惑,让我相信您实际上并未使用所有源文件进行构建。
-
你可能永远不会实例化这些类中的任何一个。
-
@JoachimPileborg 所以如果我重写代码并将所有实现内联在类定义中,它应该实例化模板并找到 push_back() 的匹配项,因此抱怨类访问?
标签: c++ templates encapsulation friend