转发声明的友元模板class不需要包含头文件
Forward declared friend template class don't need to include header file
让我们有一个抽象模板 class 堆栈,它将继承模板中第二个 class 参数的实现。
// file Stack.h
template <class T, template<typename> class Implementation>
class Stack : private Implementation<T>
{
public:
Stack() {}
virtual ~Stack() {}
void push(const T& x) { Implementation<T>::push(x); }
void pop() { Implementation<T>::pop(); }
const T& top() { return Implementation<T>::top(); }
bool empty() const { return Implementation<T>::empty(); }
};
然后,我们有一个 class 将提供实现,然后用于实例化模板。
// file ListStack.h
template <class Elem>
class ListStack
{
private:
size_t _size;
struct ListNode
{
Elem _elem;
ListNode * _next;
};
ListNode * _top;
~ListStack();
friend class Stack<Elem, ListStack>;
public:
ListStack();
bool empty() const;
const Elem& top() const;
void pop();
void push(const Elem & value);
size_t size() const;
};
我将析构函数声明为私有并将 Stack class 设为友元 class 因此它只能在实例化 Stack class 时使用。
// file main.cpp
#include "Stack.h"
#include "ListStack.h"
int main()
{
// ListStack<int> list; cannot instaniate
Stack<int, ListStack> s;
}
问题是为什么 ListStack.h 不需要包含 Stack.h 文件?
为了编译模板代码,需要在某处调用它。在您的情况下,您有两个头文件都定义了模板应该是什么。对模板的调用是在包含 Stack 和 ListStack 的文件中进行的。由于您是在 main.cpp 中创建 Stack 变量,因此您可以避免 List 和 ListStack 在头文件中彼此不认识。
我怀疑堆栈 class 将由编译器在您的 main.cpp 中定义,但我不确定我的看法是否正确。
至于ListStack class 实例化错误,那是因为你的析构函数是私有的。查看此 LINK 了解更多详情。
编辑:您还需要为您的 ListStack class 创建定义。没有它,什么都行不通。为简单起见,我假设您到处都是空定义。
让我们有一个抽象模板 class 堆栈,它将继承模板中第二个 class 参数的实现。
// file Stack.h
template <class T, template<typename> class Implementation>
class Stack : private Implementation<T>
{
public:
Stack() {}
virtual ~Stack() {}
void push(const T& x) { Implementation<T>::push(x); }
void pop() { Implementation<T>::pop(); }
const T& top() { return Implementation<T>::top(); }
bool empty() const { return Implementation<T>::empty(); }
};
然后,我们有一个 class 将提供实现,然后用于实例化模板。
// file ListStack.h
template <class Elem>
class ListStack
{
private:
size_t _size;
struct ListNode
{
Elem _elem;
ListNode * _next;
};
ListNode * _top;
~ListStack();
friend class Stack<Elem, ListStack>;
public:
ListStack();
bool empty() const;
const Elem& top() const;
void pop();
void push(const Elem & value);
size_t size() const;
};
我将析构函数声明为私有并将 Stack class 设为友元 class 因此它只能在实例化 Stack class 时使用。
// file main.cpp
#include "Stack.h"
#include "ListStack.h"
int main()
{
// ListStack<int> list; cannot instaniate
Stack<int, ListStack> s;
}
问题是为什么 ListStack.h 不需要包含 Stack.h 文件?
为了编译模板代码,需要在某处调用它。在您的情况下,您有两个头文件都定义了模板应该是什么。对模板的调用是在包含 Stack 和 ListStack 的文件中进行的。由于您是在 main.cpp 中创建 Stack 变量,因此您可以避免 List 和 ListStack 在头文件中彼此不认识。
我怀疑堆栈 class 将由编译器在您的 main.cpp 中定义,但我不确定我的看法是否正确。
至于ListStack class 实例化错误,那是因为你的析构函数是私有的。查看此 LINK 了解更多详情。
编辑:您还需要为您的 ListStack class 创建定义。没有它,什么都行不通。为简单起见,我假设您到处都是空定义。