Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/135.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/templates/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 在分离模板类的声明和定义时防止重新定义问题_C++_Templates_One Definition Rule - Fatal编程技术网

C++ 在分离模板类的声明和定义时防止重新定义问题

C++ 在分离模板类的声明和定义时防止重新定义问题,c++,templates,one-definition-rule,C++,Templates,One Definition Rule,问题是,如果通过模板制作类,然后将其包括在内,以便像往常一样使用:将得到下面解释的错误: 如果需要在Node.inl中直接使用struct。它需要包括“Node.h”头,如下所示,但这会带来一些麻烦。我们违反了一个定义的规则,但是模板类需要在声明定义时将它们的定义包含在同一个文件中。否则,编译器将忘记在创建实例时模板输出成员函数。因此,我们无法通过初始化的实例使用这些函数。那么,当我们希望保持声明和定义的独立性,而不违反一条定义规则时,我们如何管理它呢 Node.inl: #include &q

问题是,如果通过模板制作类,然后将其包括在内,以便像往常一样使用:将得到下面解释的错误:

如果需要在Node.inl中直接使用struct。它需要包括“Node.h”头,如下所示,但这会带来一些麻烦。我们违反了一个定义的规则,但是模板类需要在声明定义时将它们的定义包含在同一个文件中。否则,编译器将忘记在创建实例时模板输出成员函数。因此,我们无法通过初始化的实例使用这些函数。那么,当我们希望保持声明和定义的独立性,而不违反一条定义规则时,我们如何管理它呢

Node.inl:

#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
的唯一文件,则在这种情况下,您无法访问某个文件的成员。所以当你看到它时,你不能做任何事情。