你如何转发声明头文件?
How do you forward declare header files?
我正在尝试转发声明头文件 #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>
...
不,您不能“转发声明 header 个文件”。
为了定义给定类型的成员,必须首先定义该类型。您可以通过包含定义它的 header 来实现。
由于您在 A.hpp 中定义了 class A
并且 class 具有 std::pmr::deque<index_t>
类型的成员,因此您必须包括 std::pmr::deque
改成A.hpp,之前定义了classA
.
这是一个工作示例:
// A.hpp
#include <deque>
#include <memory_resource>
using index_t = int;
class A
{
std::pmr::deque<index_t> tempQueue;
};
根据经验法则,您不应前向声明标准库中的任何内容,除非class明确说明它可以前向声明。
要使用标准库中的任何内容,您必须实际包含它们:
// A.hpp
#include <memory_resource>
#include <deque>
class A {
std::pmr::deque<index_t> tempQueue;
}
现在,假设您没有从标准库中转发声明任何内容。您不转发声明头文件,而是转发声明 classes.
因此,如果您在 my_deque.cpp
文件中定义了一个名为 deque
的 class,在另一个文件中,您可以这样做:
// my_deque.cpp
class deque { /* some definitions ... */ };
// A.hpp
class deque;
您没有转发声明文件 my_deque
,而是转发声明 class deque
.
其次,deque
class 实际上位于命名空间中。所以为了在另一个文件中转发声明deque
,你必须在同一个命名空间中声明它:
// my_deque.cpp
namespace my_std::pmr{
class deque { /* some definitions ... */ };
}
// A.hpp
namespace my_std::pmr{
class deque;
}
第三,deque
实际上是一个模板化的 class,因此要转发声明它,您还必须在所有模板参数中声明它,包括任何具有默认参数的内容:
// 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作为class成员。为了创建 class,您必须能够计算 class 的大小。为此,您还必须知道每个 class 成员的大小。但是,你无法知道一个前向声明class的大小,因为你不知道那个class有哪些成员,所以你不能使用一个前向声明class作为 class 会员。
但是,您可以使用前向声明 class 的指针作为 class 成员,因为所有指针都具有相同的大小:
// 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;
}
我正在尝试转发声明头文件 #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>
...
不,您不能“转发声明 header 个文件”。
为了定义给定类型的成员,必须首先定义该类型。您可以通过包含定义它的 header 来实现。
由于您在 A.hpp 中定义了 class A
并且 class 具有 std::pmr::deque<index_t>
类型的成员,因此您必须包括 std::pmr::deque
改成A.hpp,之前定义了classA
.
这是一个工作示例:
// A.hpp
#include <deque>
#include <memory_resource>
using index_t = int;
class A
{
std::pmr::deque<index_t> tempQueue;
};
根据经验法则,您不应前向声明标准库中的任何内容,除非class明确说明它可以前向声明。
要使用标准库中的任何内容,您必须实际包含它们:
// A.hpp
#include <memory_resource>
#include <deque>
class A {
std::pmr::deque<index_t> tempQueue;
}
现在,假设您没有从标准库中转发声明任何内容。您不转发声明头文件,而是转发声明 classes.
因此,如果您在 my_deque.cpp
文件中定义了一个名为 deque
的 class,在另一个文件中,您可以这样做:
// my_deque.cpp
class deque { /* some definitions ... */ };
// A.hpp
class deque;
您没有转发声明文件 my_deque
,而是转发声明 class deque
.
其次,deque
class 实际上位于命名空间中。所以为了在另一个文件中转发声明deque
,你必须在同一个命名空间中声明它:
// my_deque.cpp
namespace my_std::pmr{
class deque { /* some definitions ... */ };
}
// A.hpp
namespace my_std::pmr{
class deque;
}
第三,deque
实际上是一个模板化的 class,因此要转发声明它,您还必须在所有模板参数中声明它,包括任何具有默认参数的内容:
// 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作为class成员。为了创建 class,您必须能够计算 class 的大小。为此,您还必须知道每个 class 成员的大小。但是,你无法知道一个前向声明class的大小,因为你不知道那个class有哪些成员,所以你不能使用一个前向声明class作为 class 会员。
但是,您可以使用前向声明 class 的指针作为 class 成员,因为所有指针都具有相同的大小:
// 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;
}