类 foo;在头文件中

发布于 2024-08-30 13:17:40 字数 146 浏览 8 评论 0原文

有人能解释一下为什么头文件有这样的东西吗?

class foo; // This here?
class bar
{
   bar();

};

使用这个的时候需要include语句吗?

谢谢。

Is some one able to explain why header files have something like this?

class foo; // This here?
class bar
{
   bar();

};

Do you need an include statement when using this?

Thanks.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(9

放低过去 2024-09-06 13:17:40

第一个 class foo; 被称为类 foo 的前向声明 。它只是让编译器知道它存在并且它命名了一个类。这使得 foo 成为所谓的“不完整类型”(除非已经看到 foo 的完整声明)。对于不完整类型,您可以声明该类型的指针,但无法分配该类型的实例或执行任何需要知道其大小或成员的操作。

当两种类型都可能具有指向彼此的指针时,经常使用这种前向声明,在这种情况下,两者都需要能够表达指向另一种类型的指针的概念,因此如果没有这样的东西,您将产生循环依赖。之所以需要这样做,主要是因为 C++ 使用单遍机制来解析类型;在 Java 中,无需前向声明即可拥有循环依赖关系,因为 Java 使用多次传递。您还可能会看到前向声明,其中作者有一种错误的印象,即使用前向声明而不是包含所需的标头会减少编译时间;当然,情况并非如此,因为您需要包含完整的声明(即标头),无论如何,如果使用预处理器防护,那么编译时间基本上没有区别。

要回答您是否需要包含的问题...假设您只需要部分类型,那么您的标头不需要直接包含已前向声明的类型的标头;但是,无论谁使用您的标头,当他们使用您的类型时,都需要包含前向声明类型的标头,因此您最好只包含其他标头。

The first class foo; is called a forward declaration of the class foo. It simply lets the compiler know that it exists and that it names a class. This makes foo what is called an "incomplete type" (unless the full declaration of foo has already been seen). With an incomplete type, you can declare pointers of that type, but you cannot allocate instances of that type or do anything that requires knowing its size or members.

Such forward declarations are frequently used when two types each may have pointers to each other, in which case both need to be able to express the notion of a pointer to the other type, and so you would have a circular dependency without such a thing. This is needed mostly because C++ uses a single pass mechanism for resolving types; in Java, you can have circular dependencies without forward declarations, because Java uses multiple passes. You may also see forward declarations where the author is under the misguided impression that using forward declarations instead of including the required header reduces compile time; that, of course, is not the case, because you need to include the full declaration (i.e. the header), anyway, and if preprocessor guards are used, then there is basically no difference in compile time.

To answer your question on whether you need the include or not... assuming you only need a partial type, then your header does not need to directly include the header for the type that has been forward declared; however, whoever makes use of your header, when they use your type will need to include the header for the forward declared type, and so you might as well just include the other header.

梦醒时光 2024-09-06 13:17:40

这是一个前向声明。例如,如果类 bar 有一个指向 foo 对象的指针,但您不想立即包含 foo 对象的整个定义,则需要它。

That's a forward declaration. You need it for example if class bar has a pointer to a foo object, but you don't want to include the whole definition of the foo object immediately.

匿名。 2024-09-06 13:17:40

这是该类的前向声明。
根据我的经验,这通常是在有循环依赖时完成的......例如

in foo.h
--------
#include "bar.h"

class foo
{
public:
    foo(bar *bar);
private:
    foo *m_foo;
};

and in bar.h
------------
class foo;
class bar
{
public:
    void methodFooWillCall();
protected:
    std::list<foo *> myFoos;
}

this is a forward declaration of the class.
In my experience, this is typically done when you have a circular dependency.. for example

in foo.h
--------
#include "bar.h"

class foo
{
public:
    foo(bar *bar);
private:
    foo *m_foo;
};

and in bar.h
------------
class foo;
class bar
{
public:
    void methodFooWillCall();
protected:
    std::list<foo *> myFoos;
}
十二 2024-09-06 13:17:40

只是好奇,为什么我们需要术语“前向声明”?前向声明不就是一个声明(而不是定义)吗?

class X;  // declaration

class X   // definition
{
    int member;
    void function();
};

Just curious, why do we need the term forward declaration at all? Isn't a forward declaration simply a declaration (as opposed to a definition)?

class X;  // declaration

class X   // definition
{
    int member;
    void function();
};
我是男神闪亮亮 2024-09-06 13:17:40

这是一个前瞻性声明。考虑以下示例:

class foo; // you likely need this for the code beneath to compile
class bar {
    void smth( foo& );
};

如果您没有以编译器在编译 class bar 的定义之前看到它的方式包含 class foo 的定义,则代码将不会编译(编译器会说它不知道 foo 的含义),除非你有前向声明。

That's a forward declaration. Consider the following example:

class foo; // you likely need this for the code beneath to compile
class bar {
    void smth( foo& );
};

If you haven't included the definition of class foo in such a way that the compiler sees it before compiling the definition of class bar the code will not compile (the compiler will say it doesn't know what foo means) unless you have the forward declaration.

听不够的曲调 2024-09-06 13:17:40

这是“foo”类的前向声明。它允许您声明类的指针和引用,但不能使用它(例如调用成员或确定其大小),因为它尚未定义!随后必须跟上完整的正常声明 (class foo { ... };)。

它对于声明两个相互保存指针的类非常有用,否则将无法设置它们。

It's a forwards declaration of the class 'foo'. It allows you to declare pointers and references to the class, but not use it (eg. call members or determine its size), because it's not yet defined! It must later be followed up with a full, normal declaration (class foo { ... };).

It's useful for things like declaring two classes which hold pointers to each other, which otherwise would be impossible to set up.

最舍不得你 2024-09-06 13:17:40

这称为前向声明。类 foo 的主体将在文件的后面部分定义。进行前向声明是为了避免循环依赖:类 Bar 的定义需要类 Foo,反之亦然。

class Bar
{
   Foo * foo;
};
class Foo
{
   Bar * bar;
};

如您所见,Bar 引用了 Foo,反之亦然。如果您尝试编译它,编译器会抱怨说它不知道有关 Foo 的任何信息。解决方案是在 Bar 上方声明 class Foo (就像在 main 上方声明函数的原型并定义其主体一样)之后)。

class Foo; //Tells the compiler that there is a class Foo coming down the line.
class Bar
{
   Foo * foo;
};
class Foo
{
   Bar * bar;
};

This is called forward declaration. The body of the class foo would be defined at a later part of the file. Forward declaration is done to get around cyclic dependencies: The definition of class Bar requires class Foo and vice versa.

class Bar
{
   Foo * foo;
};
class Foo
{
   Bar * bar;
};

As you can see, Bar has a reference to Foo and vice versa. If you try to compile this, the compiler will complaint saying that it doesn't know anything about Foo. The solution is to forward declare the class Foo above the Bar (just like you declare the prototype of a function above the main and define its body later).

class Foo; //Tells the compiler that there is a class Foo coming down the line.
class Bar
{
   Foo * foo;
};
class Foo
{
   Bar * bar;
};
笨死的猪 2024-09-06 13:17:40

这称为前向声明。它用于让您的代码知道类 foo 的存在。这又可以被类栏使用。

它通常用于解决循环包含问题。以此为例

//a.h
#include "b.h"

class A
{
    void useB(B obj);
}

// b.h
#include "a.h"
class B
{
     void useA(A obj);
}

这会导致循环包含问题,因为 ah 包含 bh,bh 又包含 ah,直到无穷大。您可以通过在每个标头中对每个类进行前向声明来解决此问题,如下所示:

//a.h
class B;

class A
{
    void useB(B obj);
}

// b.h
class A;

class B
{
     void useA(A obj);
}

注意: 通常,当您遇到循环包含问题时,这表明存在概念/建模问题。在尝试使用前向声明解决问题之前,您可能应该问自己您的类是否定义良好。

This is called a forward declaration. It is used to make your code aware that the class foo exists. This in turn can be used by the class bar.

It's commonly used to solve circular includes problems. Take this for example

//a.h
#include "b.h"

class A
{
    void useB(B obj);
}

and

// b.h
#include "a.h"
class B
{
     void useA(A obj);
}

This causes a circular include problem, because a.h includes b.h which in turns includes a.h, to infinity. You can solve this problem by making a forward declaration of each class in each header, like so :

//a.h
class B;

class A
{
    void useB(B obj);
}

// b.h
class A;

class B
{
     void useA(A obj);
}

Note : Very often when you have a circular include problem, this is indicative of a conception/modelling problem. You should probably ask yourself if your classes are well defined before trying to solve your problem with forward declarations.

国粹 2024-09-06 13:17:40

尝试考虑这样写:

file bar.h:

        #include "bar.h"

        class Foo
        {
        Bar* bar_ptr;
        }

file foo.h:

        #include "foo.h"

        class Bar
        {
            Foo* foo_ptr;
        }

这是行不通的,首先是由于无限的 #include 链,然后如果你删除其中一个包含,则 Foo 将不知道 Bar 是什么是,否则 Bar 不会知道 Foo 是什么。

试试这个:

        class Bar;

        class Foo
        {
        Bar* bar_ptr;
        };

文件 foo.h:

        class Foo;

        class Bar
        {
            Foo* foo_ptr;
        };

Try to think of writing this:

file bar.h:

        #include "bar.h"

        class Foo
        {
        Bar* bar_ptr;
        }

file foo.h:

        #include "foo.h"

        class Bar
        {
            Foo* foo_ptr;
        }

This won't work, first due to infinite #include chain, then if you get rid of one of the includes, either Foo won't know what Bar is, or Bar won't know what Foo is.

Try this instead:

        class Bar;

        class Foo
        {
        Bar* bar_ptr;
        };

file foo.h:

        class Foo;

        class Bar
        {
            Foo* foo_ptr;
        };
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文