Forward Declaration vs Include

陌路散爱 提交于 2020-01-09 09:04:55

问题


Consider the following two scenarios (Edited just to complete the whole question and make it clearer)

Case 1: (doesnt compile as rightly mentioned below)

//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)

//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?

Edit: So how do I make scenario 1 work.


回答1:


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.

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).




回答2:


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.

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 use the members of the forward declared class.

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...

But having said that, when the compiler requires the definition of the class, it should be #included..

So, in your case A obj; requires the definition of class A and hence you should #include..

I myself asked a similar question here and another similar question which has also a nice answer...

Hope it helps..




回答3:


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.




回答4:


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.




回答5:


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.

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 :)

.. 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.




回答6:


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.

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).



来源:https://stackoverflow.com/questions/3632818/forward-declaration-vs-include

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!