What are the dangers of forward declarations?

前端 未结 9 1428
轻奢々
轻奢々 2021-02-01 16:58

I just had an interview. I was asked what is a \"forward declaration\". I was then asked if they were dangers associated with forward declarations.

I could not answer to

相关标签:
9条回答
  • 2021-02-01 17:22

    Forward declaration is the symptom of C++ missing modules (going to be fixed in C++17?) and using headers inclusion, if C++ had modules there were no need at all for forward declarations.

    A forward declaration is not less than a "contract", by using it you actually promise that you will provide the implementation of something (after in the same source file, or by linking a binary later).

    The cons of that is that you actually have to follow your contract, not much very an issue because if you don't follow your contract the compiler will somehow complain early, but in some languages code just get executed without the need to "promise its own existence" (speaking of dynamically typed languages)

    0 讨论(0)
  • 2021-02-01 17:22

    I'd say any danger is eclipsed by the gains. There are some though, mostly related to refactoring.

    • renaming classes impacts all forward-declarations. This of course also comes with includes, but the error is generated in a different place, so harder to spot.
    • moving classes from a namespace to another, coupled with using directives, can wreak havoc (mysterious errors, hard to spot and fix) - of course, the using directives are bad to start off with, but no code is perfect, right?*
    • templates - to forward declare templates (esp. user-defined ones) you'll need the signature, which leads to code duplication.

    Consider

    template<class X = int> class Y;
    int main()
    {
        Y<> * y;
    }
    
    //actual definition of the template
    class Z
    {  
    };
    template<class X = Z> //vers 1.1, changed the default from int to Z
    class Y
    {};
    

    The class Z was changed afterwards as the default template argument, but the original forward declaration is still with int.

    *I've recently ran into this:

    Original:

    Definition:

    //3rd party code
    namespace A  
    {
       struct X {};
    }
    

    and forward declaration:

    //my code
    namespace A { struct X; }
    

    After refactoring:

    //3rd party code
    namespace B
    {
       struct X {};
    }
    namespace A
    {
       using ::B::X;
    }
    

    This obviously rendered my code invalid, but the error wasn't at the actual place and the fix was, to say the least, fishy.

    0 讨论(0)
  • 2021-02-01 17:32

    A forward declaration is not so much dangerous in itself, but it is a code smell. If you need a forward declaration, it means two classes are tightly coupled, which usually is bad. Thus it is an indication that your code may need refactoring.

    There are some cases where it is OK to have tight coupling, e.g. the concrete states in a state pattern implementation may be tightly coupled. I would consider this OK. But in most other cases, I would improve my design before using a forward declaration.

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