What are the drawbacks of forward declaration?

前端 未结 5 1353
暗喜
暗喜 2021-01-14 13:09

I am wondering if there is any drawback for using forward declarations in all places when possible. This is if my header contains only declarations.

As far as I unde

相关标签:
5条回答
  • 2021-01-14 13:37

    Using forward declarations improves decoupling. If you can avoid including "A.h" by using a forward declaration, it is a good idea to use forward declaration. It is better not only because your builds run faster (after all, preprocessed headers can deal with compiler efficiency pretty well) but because it tells the readers of your declaration that the structure of your class B does not depend on knowing anything about your class A, other than that it exists*.

    EDIT (to answer your question) The only downside to forward declarations that I know is that you cannot use them in all situations: for example, a declaration similar to this:

    class B
    {
        A myA[10];
    };
    

    would not compile, because the compiler needs to know the size of A. However, the compiler finds such issues very reliably, and informs you about them in unambiguous terms.

    * The implementation of class B could very well depend on knowing the details of class A. However, this dependency becomes an implementation detail of B hidden from the users of your class; you can change it at any time without breaking the code dependent upon class B.

    0 讨论(0)
  • 2021-01-14 13:41

    Forward declaration is the only way to break the cyclic inclusion.

    This is the main drawback when not used carefully, I think. I worked in a large project where forward declarations are made whenever possible. Cyclic dependencies were a real problem in the end.

    0 讨论(0)
  • 2021-01-14 13:43

    The only drawback that comes to mind is that forward declarations require pointers. Therefore they may not be initialized and therefore could cause a null reference exception. As the coding standard that I currently use, requires all pointers require a null reference check if can add allot of code. I started to get around this with a Design By Contract invariants; then I can assert that anything initialized in the constructor never be null.

    0 讨论(0)
  • 2021-01-14 13:48

    using forward declaration speeds up compiler time

    This is partially true, because the compiler (and preprocessor) do not need to parse included headers in every file you include this header.

    The real improvement you see when you change the header and need to recompile.

    Forward declaration is the only way to break the cyclic inclusion.

    0 讨论(0)
  • 2021-01-14 13:49

    I'll speak in practical terms. Pros:

    1. Avoids circular compiler dependencies. The way you wrote the code above would not even compile otherwise unless you put A and B in the same header.

    2. It avoids compile-time dependencies. You're allowed to change a.h without recompiling units that include b.h. For the same reason, it speeds up builds in general. To find out more on this subject, I recommend looking up the Pimpl idiom.

    Cons:

    1. Applied heavily in this way you have above, your general source files will probably need to include more headers (we cannot instantiate or work with A simply by including B.h). To me, that's a worthwhile exchange for faster builds.

    2. This is probably the biggest con which is that it can come with some runtime overhead depending on what you are doing. In the example you gave, B cannot directly store A as a value. It involves a level of indirection, which may also imply an extra heap allocation/deallocation if B is the memory manager of A (the same would be true of a pimpl). Whether this overhead is trivial or not is where you have to draw the line, and it's worth remembering that maintainability and developer productivity is definitely more important than a micro-optimization which won't even be noticeable to the user. I wouldn't use this as a reason to rule out this practice unless it is definitely proving to be a bottleneck or you know well in advance that the cost of a heap allocation/deallocation or pointer indirection is going to be a non-trivial overhead.

    0 讨论(0)
提交回复
热议问题