Forward Declaration of a Base Class

前端 未结 6 629
旧巷少年郎
旧巷少年郎 2020-12-10 01:57

I\'m trying to create proper header files which don\'t include too many other files to keep them clean and to speed up compile time.

I encountered two problems while

6条回答
  •  南方客
    南方客 (楼主)
    2020-12-10 02:55

    As answered before by Earwicker, you can not use forward declarations in any of those cases as the compiler needs to know the size of the class.

    You can only use a forward declaration in a set of operations:

    • declaring functions that take the forward declared class as parameters or returns it
    • declaring member pointers or references to the forward declared class
    • declaring static variables of the forward declared type in the class definition

    You cannot use it to

    • declare a member attribute of the given type (compiler requires size)
    • define or create an object of the type or delete it
    • call any static or member method of the class or access any member or static attribute

    (did I forget any?)

    Take into account that declaring an auto_ptr is not the same as declaring a raw pointer, since the auto_ptr instantiation will try to delete the pointer when it goes out of scope and deleting requires the complete declaration of the type. If you use an auto_ptr in to hold a forward declared type you will have to provide a destructor (even if empty) and define it after the full class declaration has been seen.

    There are also some other subtleties. When you forward declare a class, you are telling the compiler that it will be a class. This means that it cannot be an enum or a typedef into another type. That is the problem you are getting when you try to forward declare std::string, as it is a typedef of a specific instantiation of a template:

    typedef basic_string string; // aproximate
    

    To forward declare string you would need to forward declare the basic_string template and then create the typedef. The problem is that the standard does not state the number of parameters that basic_string template takes, it just states that if it takes more than one parameter, there rest of the parameters must have a default type so that the expression above compiles. This means that there is no standard way for forward declaring the template.

    If, on the other hand you want to forward declare a non-standard template (non STL, that is) you can do it for as long as you do know the number of parameters:

    template  class Test; // correct
    //template  class Test; // incorrect even if U has a default type
    
    template  class Test {
       // ...
    };
    

    At the end, the advice that was given to you by Roddy: forward declare as much as you can, but assume that some things must be included.

提交回复
热议问题