In C++, is it possible to forward declare a class as inheriting from another class?

后端 未结 5 1454
忘了有多久
忘了有多久 2020-11-29 04:46

I know that I can do:

class Foo;

but can I forward declare a class as inheriting from another, like:

class Bar {};

class F         


        
5条回答
  •  谎友^
    谎友^ (楼主)
    2020-11-29 05:35

    No it is not possible to forward declare inheritance, even if you are only dealing with pointers. When dealing with conversions between pointers, sometimes the compiler has to know the details of the class to do the conversion correctly. This is the case with multiple inheritance. (You could special case some parts parts of the hierarchy that only use single inheritance, but that isn't part of the language.)

    Consider the following trivial case:

    #include 
    class A { int x; };
    class B { int y; };
    class C: public A, public B { int z; };
    void main()
    { 
        C c; A *pa = &c; B *pb = &c; C *pc = &c; 
        printf("A: %p, B: %p, C: %p\n", pa, pb, pc);
    }
    

    The output I received (using 32 bit visual studio 2010), is:

    A: 0018F748, B: 0018F74C, C: 0018F748
    

    So for multiple inheritance, when converting between related pointers, the compiler has to insert some pointer arithmetic to get the conversions right.

    This is why, even if you are dealing only with pointers, you can't forward declare inheritance.

    As for why it would be useful, it would improve compile times when you do want to make use of co-variant return types instead of using casts. For example this will not compile:

    class RA;
    class A             { public: virtual RA *fooRet(); };
    class RB;
    class B : public A  { public: virtual RB *fooRet(); };
    

    But this will:

    class RA;
    class A             { public: virtual RA *fooRet(); };
    class RA { int x; };
    class RB : public RA{ int y; };
    class B : public A  { public: virtual RB *fooRet(); };
    

    This is useful when you have objects of type B (not pointers or references). In this case the compiler is smart enough to use a direct function call, and you can use the return type of RB* directly without casting. In this case, usually I go ahead and make the return type RA * and do a static cast on the return value.

提交回复
热议问题