C++ 在分离模板类的声明和定义时防止重新定义问题
问题是,如果通过模板制作类,然后将其包括在内,以便像往常一样使用:将得到下面解释的错误: 如果需要在Node.inl中直接使用struct。它需要包括“Node.h”头,如下所示,但这会带来一些麻烦。我们违反了一个定义的规则,但是模板类需要在声明定义时将它们的定义包含在同一个文件中。否则,编译器将忘记在创建实例时模板输出成员函数。因此,我们无法通过初始化的实例使用这些函数。那么,当我们希望保持声明和定义的独立性,而不违反一条定义规则时,我们如何管理它呢 Node.inl:C++ 在分离模板类的声明和定义时防止重新定义问题,c++,templates,one-definition-rule,C++,Templates,One Definition Rule,问题是,如果通过模板制作类,然后将其包括在内,以便像往常一样使用:将得到下面解释的错误: 如果需要在Node.inl中直接使用struct。它需要包括“Node.h”头,如下所示,但这会带来一些麻烦。我们违反了一个定义的规则,但是模板类需要在声明定义时将它们的定义包含在同一个文件中。否则,编译器将忘记在创建实例时模板输出成员函数。因此,我们无法通过初始化的实例使用这些函数。那么,当我们希望保持声明和定义的独立性,而不违反一条定义规则时,我们如何管理它呢 Node.inl: #include &q
#include "Node.h"
void foo(){
struct Something s{1, 2};
}
template <class T>
Node<T>::Node(int data, Node<T> *next) : m_data{data}, m_next{next} {}
template <class T>
void Node<T>::setData(int data) {
m_data = data;
}
template <class T>
int Node<T>::getData() const {
return m_data;
}
template <class T>
void Node<T>::setNext(Node<T> *next) {
m_next = next;
}
template <class T>
Node<T> * Node<T>::getNext() const {
return m_next;
}
template <class T>
void Node<T>::allocMemoryNext() {
m_next = new Node<T>();
}
#包括“Node.h”
void foo(){
结构某物s{1,2};
}
模板
Node::Node(int data,Node*next):m_data{data},m_next{next}{
模板
void节点::setData(int数据){
m_data=数据;
}
模板
int节点::getData()常量{
返回m_数据;
}
模板
void节点::setNext(节点*next){
m_next=next;
}
模板
Node*Node::getNext()常量{
下一步返回m_;
}
模板
void节点::allocMemoryNext(){
m_next=新节点();
}
节点h:
#ifndef THE1_NODE_H
#define THE1_NODE_H
struct Something{
int x;
int y;
};
template <class T>
class Node {
private:
T m_data;
Node *m_next;
public:
explicit Node(int data = 0, Node *next = nullptr);
void setData(int data);
[[nodiscard]] int getData() const;
void setNext(Node *next);
[[nodiscard]] Node *getNext() const;
void allocMemoryNext();
};
#include "Node.inl"
#endif //THE1_NODE_H
#如果1_节点
#定义1_节点
构造某物{
int x;
int-y;
};
模板
类节点{
私人:
T m_数据;
Node*m_next;
公众:
显式节点(int data=0,Node*next=nullptr);
无效设置数据(int数据);
[[nodiscard]]int getData()常量;
void setNext(节点*next);
[[nodiscard]]Node*getNext()常量;
void allocMemoryNext();
};
#包括“Node.inl”
#endif//1_节点
我们希望保持声明和定义的独立性
就模板而言,不存在这种“分离性”。为了让任何人使用它们,必须定义它们。Node.h提供了这些定义
Node.inl是Node.h的一部分。您已经在逻辑上将文本分为不同的文件,但就任何实际情况而言,它们并不是分开的。Node.h的每个用户也应该获得Node.inl的内容,这就是为什么在文件末尾包含“Node.inl”。只有Node.h应该包含Node.inl,因此Node.inl没有理由包含“Node.h”
因此,一旦删除了肯定已经存在的内容的不必要的包含,就没有问题了。但是我可能想使用“Node.inl”中“Node.h”中定义的结构,所以我需要包含。事实上,这就是被问到的问题。@ibrahimkoz:不,你不需要包括任何这样的东西。C++中的文件不是分开的、锁着的构造。code>#includesion只是将文本从一个文件复制/粘贴到另一个文件中。Node.inl包含在Node.h中的一组定义之后,因此它可以访问这些定义。不,您错了,需要包含类和结构才能就地使用。@ibrahimkoz:它们不需要被“包含”;它们必须是可见的。它们是可见的。从
Node.inl
文件中删除#include“Node.h”
,您会发现它可以看到一些东西。如果Node.h
是包含Node.inl
的唯一文件,则在这种情况下,您无法访问某个文件的成员。所以当你看到它时,你不能做任何事情。