C++ 前向声明与包含
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/3632818/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Forward Declaration vs Include
提问by Sii
Consider the following two scenarios (Edited just to complete the whole question and make it clearer)
考虑以下两种情况(编辑只是为了完成整个问题并使其更清晰)
Case 1: (doesnt compile as rightly mentioned below)
情况 1 :(没有正确地编译如下所述)
//B.h
#ifndef B_H
#define B_H
#include "B.h"
class A;
class B {
A obj;
public:
void printA_thruB();
};
#endif
//B.cpp
#include "B.h"
#include <iostream>
void B::printA_thruB(){
obj.printA();
}
//A.h;
#ifndef A_H
#define A_H
#include "A.h"
class A {
int a;
public:
A();
void printA();
};
#endif
//A.cpp
#include "A.h"
#include <iostream>
A::A(){
a=10;
}
void A::printA()
{
std::cout<<"A:"<<a<<std::endl;
}
//main.cpp
#include "B.h"
#include<iostream>
using namespace std;
int main()
{
B obj;
obj.printA_thruB();
}
Case 2: (the only modifications...works without compiliation error)
案例 2:(唯一的修改......没有编译错误的作品)
//B.h
#include "A.h" //Add this line
//class A; //comment out this line
Let us assume both the A.cpp and B.cpp are complied together. Do the above two scenarios make any differences? Is there a reason to prefer one method over the other?
让我们假设 A.cpp 和 B.cpp 一起编译。以上两种情况有什么区别吗?是否有理由更喜欢一种方法而不是另一种方法?
Edit: So how do I make scenario 1 work.
编辑:那么我如何使场景 1 工作。
采纳答案by Drew Hall
Case 1 will produce an "incomplete type" error when you compile B.cpp. Because class B contains a class A object, the definition (and in particular the size) of class A is required to be complete before the definition of class B.
情况 1 在编译 B.cpp 时会产生“类型不完整”错误。因为 B 类包含一个 A 类对象,所以 A 类的定义(尤其是大小)需要在 B 类定义之前完成。
Alternatively, you could choose to make some_variable a pointer or reference to class A, and in that case your forward declaration would be sufficient in B.h. You'd still need a full definition of A in B.cpp (assuming you made actual use of the A member functions/data).
或者,您可以选择使 some_variable 成为类 A 的指针或引用,在这种情况下,您的前向声明在 Bh 中就足够了您仍然需要在 B.cpp 中对 A 进行完整定义(假设您实际使用了成员函数/数据)。
回答by liaK
Forward declaration is not a substitute for Header file inclusion.
前向声明不能替代头文件包含。
As the name itself implies, forward declaration is just a Declaration
and not a definition.
顾名思义,前向声明只是 aDeclaration
而不是 definition。
So, you will declare saying the compiler that it is a class and I just declaring it here and will provide you the definition when am gonna use it. So, normally you forward declare
in the Header file and #include
in the .cpp file where you will usethe members of the forward declared class.
因此,您将声明编译器它是一个类,而我只是在此处声明它,并在我要使用它时为您提供定义。因此,通常您会forward declare
在头文件和#include
.cpp 文件中使用前向声明类的成员。
By doing so, what you make is, wherever you are including the header file there will just be a declaration for the class instead of the entire contents #included
...
通过这样做,你所做的是,无论你在哪里包含头文件,都会有一个类的声明而不是整个内容#included
......
But having said that, when the compiler requires the definition of the class, it should be #included
..
不过话说回来,当编译器要求定义类的时候,应该是#included
..
So, in your case A obj;
requires the definition of class A
and hence you should #include
..
因此,在您的情况下A obj;
需要定义,class A
因此您应该#include
..
I myself asked a similar question hereand another similar questionwhich has also a nice answer...
我自己在这里问了一个类似的问题,另一个 类似的问题也有一个很好的答案......
Hope it helps..
希望能帮助到你..
回答by Hitesh
You need to use forward declarations in cases where you have classes that refer to each other.
如果您有相互引用的类,则需要使用前向声明。
//A.h
class B;
class A {
B* someVar;
}
//B.h
#include <A.h>
class B {
A* someVar;
}
But there's no benefit for doing it in the case you laid out.
但是在您布置的情况下这样做没有任何好处。
回答by Mark Ransom
Think like a compiler. In order to create an A
inside of B
, the compiler has to know how to build an A
, and the only way to do that is to have the complete definition. The forward declaration tells the compiler that class A
exists without describing what it looks like; this is adequate for defining a pointer or a reference. When it comes time to use that pointer or reference, the complete class definition will be required.
像编译器一样思考。为了创建一个A
内部的B
,编译器必须知道如何构建一个A
,而唯一的方法就是拥有完整的定义。前向声明告诉编译器该类A
存在而不描述它的样子;这足以定义指针或引用。当需要使用该指针或引用时,将需要完整的类定义。
回答by Arnold Spence
If you meant to portray some_variable as a pointer then the frequently recommended practice is to use forward declarations whenever possible to avoid the overhead of includes and longer compile times.
如果您打算将 some_variable 描述为指针,那么经常推荐的做法是尽可能使用前向声明,以避免包含的开销和更长的编译时间。
I'm all for best practices but I really like using IDEs that have nice code navigation features and forwards cause a problem there, at least with Netbeans. Whenever I try to navigate to a type declaration, I always end up at the forward and not the .h file containing the actual declaration. I'm willing to accept some extra compile time for the ease of navigation. Maybe this is just a problem with Netbeans :)
我完全赞成最佳实践,但我真的很喜欢使用具有良好代码导航功能的 IDE,并且转发会导致问题,至少对于 Netbeans。每当我尝试导航到类型声明时,我总是以前进的方式结束,而不是包含实际声明的 .h 文件。为了便于导航,我愿意接受一些额外的编译时间。也许这只是 Netbeans 的一个问题:)
.. oh yeah.. If you look at the related questions to the right of your question, you will find lots of additional information of forward declarations.
.. 哦是的.. 如果您查看问题右侧的相关问题,您会发现很多关于前向声明的附加信息。
回答by mike
For case 1, compiler will complain with "incomplete type" for class B because class B contains a class A object, and you did not tell B any detail of class A, so compiler cann't decide the size of object B.
对于情况 1,编译器会抱怨 B 类的“类型不完整”,因为 B 类包含一个 A 类对象,而您没有告诉 B 类 A 的任何细节,因此编译器无法决定对象 B 的大小。
For your case, you can use A& obj
or A* obj
instead of A obj
, since the size of a reference/pointer is const(4/8 for 32bit/64bit CPU).
对于您的情况,您可以使用A& obj
或A* obj
代替A obj
,因为引用/指针的大小为 const(32 位/64 位 CPU 为 4/8)。