简体   繁体   English

你如何转发声明 header 文件?

[英]How do you forward declare header files?

I'm trying to forward declare the header files #include<memory_resource> and #include<deque> .我正在尝试转发声明 header 文件#include<memory_resource>#include<deque> But the following doesn't seem to work.但以下似乎不起作用。 This is pseudo-code:这是伪代码:

A.hpp A.hpp

class memory_resource;
class deque;

class A
{
public:
    ...

private:
    std::pmr::deque<index_t> tempQueue;
}

A.cpp A.cpp

#include<memory_resource>
#include<deque>

...

No, you cannot "forward declare header files".不,您不能“转发声明 header 文件”。

In order to define a member of a given type, that type must first be defined.为了定义给定类型的成员,必须首先定义该类型。 You can achieve that by including the header that defines it.您可以通过包含定义它的 header 来实现这一点。

Since you define the class A in A.hpp and that class has a member of type std::pmr::deque<index_t> , you must include the definition of std::pmr::deque into A.hpp, before the definition of the class A .由于您在 A.hpp 中定义了 class A并且 class 具有std::pmr::deque<index_t>类型的成员,因此您必须在定义之前将std::pmr::deque的定义包含到 A.hpp 中class A

Here is a working example:这是一个工作示例:

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

For a rule of thumb , you should not forward declare anything from the standard library, unless the class specifically says it can be forward declared.根据经验,您不应从标准库中转发声明任何内容,除非 class 明确表示可以转发声明。

To use anything from the standard library, you must actually include them:要使用标准库中的任何内容,您必须实际包含它们:

// A.hpp
#include <memory_resource>
#include <deque>

class A {
    std::pmr::deque<index_t> tempQueue;
}

Now, let's pretend you are not forward declaring anything from the standard library.现在,让我们假设您没有从标准库中向前声明任何内容。 You don't forward declare header files, instead you forward declare classes.您不转发声明 header 文件,而是转发声明类。

So if you have a class named deque defined in my_deque.cpp file, in another file, you might do:因此,如果您在my_deque.cpp文件中定义了一个名为deque的 class ,则在另一个文件中,您可能会这样做:

// my_deque.cpp

class deque { /* some definitions ... */ };

// A.hpp

class deque;

You don't forward declare the file, my_deque , instead you forward declare the class deque .您不转发声明文件my_deque ,而是转发声明 class deque


Secondly, the deque class was actually located in a namespace.其次, deque class 实际上位于命名空间中。 So in order to forward declare deque in another file, you must declare it within the same namespace:因此,为了在另一个文件中转发声明deque ,您必须在同一命名空间中声明它:

// my_deque.cpp

namespace my_std::pmr{
    class deque { /* some definitions ... */ };
}

// A.hpp

namespace my_std::pmr{
    class deque;
}

Third, deque was actually a templated class, so to forward declare it, you must also declare it along all the template argument, including anything with default arguments:第三, deque实际上是一个模板化的 class,所以要转发声明它,您还必须在所有模板参数中声明它,包括默认 arguments 的任何内容:

// 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;
}

Fourth, you cannot use a forward declared class as a class member directly.第四,您不能直接使用前向声明的 class 作为 class 成员。 In order to create a class, you must be able to calculate the size of the class.为了创建 class,您必须能够计算 class 的大小。 To do that, you must also know the sizes of each class members.为此,您还必须知道每个 class 成员的大小。 However, you can't know the size of a forward declared class, because you don't know what members does that class have, so you can't use a forward declared class as a class member. However, you can't know the size of a forward declared class, because you don't know what members does that class have, so you can't use a forward declared class as a class member.

However, you can use a pointer of a forward declared class as a class member, since all pointers have the same size:但是,您可以使用前向声明的 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;
}

I would like to attempt to clear the confusion about forward declaration.我想尝试消除关于前向声明的混淆。

You can forward-declare types if you don't need to know anything about them in the current file.如果您不需要了解当前文件中的任何类型,则可以前向声明类型。 For example, if your class A contained a pointer to the deque , you could have:例如,如果您的class A包含指向deque的指针,您可以:

class std::pmr::deque;

class A
{
public:
    ...

private:
    std::pmr::deque<index_t>* ptempQueue;
}

Then you would include those header files in your A.cpp .然后,您将在A.cpp中包含那些 header 文件。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM