如何转发声明头文件



我正在尝试转发声明头文件#include<memory_resource>#include<deque>。但以下内容似乎不起作用。这是伪代码:

A.hpp

class memory_resource;
class deque;
class A
{
public:
...
private:
std::pmr::deque<index_t> tempQueue;
}

A.cpp

#include<memory_resource>
#include<deque>
...

不,您不能"前向声明头文件";。

为了定义给定类型的成员,必须首先定义该类型。你可以通过包含定义它的标题来实现这一点

由于在A.hpp中定义了类A,并且该类具有类型为std::pmr::deque<index_t>的成员,因此必须在定义类A之前将std::pmr::deque的定义包含在A.hpp中。

下面是一个工作示例:

// A.hpp
#include <deque>
#include <memory_resource>
using index_t = int;
class A
{
std::pmr::deque<index_t> tempQueue;
};

对于经验规则,您不应该转发声明标准库中的任何内容,除非该类明确表示可以转发声明。

要使用标准库中的任何内容,实际上必须包含它们:

// A.hpp
#include <memory_resource>
#include <deque>
class A {
std::pmr::deque<index_t> tempQueue;
}

现在,让我们假设您没有正向声明标准库中的任何内容。您不转发声明头文件,而是转发声明类。

因此,如果在my_deque.cpp文件中定义了一个名为deque的类,那么在另一个文件中,您可以执行以下操作:

// my_deque.cpp
class deque { /* some definitions ... */ };
// A.hpp
class deque;

您不转发声明文件my_deque,而是转发声明类deque


其次,deque类实际上位于命名空间中。因此,为了在另一个文件中转发声明deque,您必须在同一个命名空间中声明它:

// my_deque.cpp
namespace my_std::pmr{
class deque { /* some definitions ... */ };
}
// A.hpp
namespace my_std::pmr{
class deque;
}

第三,deque实际上是一个模板化的类,所以要转发声明它,还必须连同所有模板参数一起声明它,包括任何带有默认参数的类:

// my_deque.cpp
namespace my_std::pmr{
template<typename T, typename Allocator = std::allocator<T>>
class deque { /* some definitions ... */ };
}
// A.hpp
namespace my_std::pmr{
template<typename T, typename Allocator = std::allocator<T>>
class deque;
}

第四,不能将正向声明的类直接用作类成员。为了创建一个类,您必须能够计算类的大小。要做到这一点,你还必须知道每个班级成员的规模。但是,您不能知道正向声明类的大小,因为您不知道该类有什么成员,所以不能将正向声明类用作类成员。

但是,您可以使用前向声明类的指针作为类成员,因为所有指针的大小都相同:

// my_deque.cpp
namespace my_std::pmr{
template<typename T, typename Allocator = std::allocator<T>>
class deque { /* some definitions ... */ };
}
// A.hpp
namespace my_std::pmr{
template<typename T, typename Allocator = std::allocator<T>>
class deque;
}
class A{
my_std::pmr::deque<index_t>* p_tempQueue;
}

最新更新