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

I know what I can do:

class Foo; 

but I can forward the declaration as inheritance from another, for example:

 class Bar {}; class Foo: public Bar; 



An example of use is the option of sharing links.

 // somewhere.h class RA {} class RB : public RA {} 

... and then in another heading that doesn't include anywhere. h

 // other.h class RA; class A { public: virtual RA* Foo(); // this only needs the forward deceleration } class RB : public RA; // invalid but... class B { public: virtual RB* Foo(); // } 

The only information that the compiler needs to process to declare an RB* B:Foo() declaration RB* B:Foo() is that RB has RA as a public base class. Now, obviously, you'll need it somewhere. H, if you intend to do any dereference of return values ​​from Foo . However, if some customers never call Foo , then there is no reason to include them somewhere. H, which can significantly speed up compilation.

+46
c ++ inheritance forward-declaration
Jan 29 '10 at 1:52
source share
4 answers

A direct declaration is really useful for telling the compiler that a class with that name exists and will be declared and defined elsewhere. You cannot use it in any case when the compiler needs contextual information about the class, and the compiler does not need to tell you only a little about it. (Typically, you can only use the forward declaration when accessing this class without another context, for example, as a parameter or return value.)

So you cannot forward declare Bar in any scenario where you then use it to help declare Foo, and it makes no sense to have a forward declaration that includes the base class - what does it tell you, among other things?

+32
Jan 29 '10 at 1:56
source share

Variable declarations are declarations, not definitions. So, everything that requires a class declaration (for example, pointers to this class) needs only a direct declaration. However, anything that would require a definition, that is, would have to know the actual structure of the class, would not work only with direct declaration.

Derived classes should definitely know the structure of their parent, and not just that the parent exists, so a direct declaration would be insufficient.

+33
Jan 29 '10 at 2:06
source share

There is no forwarding of the inheritance declaration, even if you only deal with pointers. When it comes to conversions between pointers, sometimes the compiler needs to know the details of the class in order to make the conversion right. This applies to multiple inheritance. (In a particular case, we can distinguish some parts of the parts of the hierarchy that use only one inheritance, but this is not part of the language.)

Consider the following trivial case:

 #include <stdio.h> 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 result obtained (using 32-bit visual studio 2010):

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

So, for multiple inheritance when converting adjacent pointers, the compiler must insert some pointer arithmetic to get the correct conversions.

That is why, even if you are dealing only with pointers, you cannot redirect the declaration of inheritance.

As to why this would be useful, it would improve compilation times when you want to use the return types of co-options instead of using throws. 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 it will be:

 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 if 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 returned type RB * directly without casting. In this case, as a rule, I go ahead and do the return type RA * and perform a static action on the return value.

+14
Apr 13 2018-12-12T00:
source share

I do not find this useful. Consider: you defined a class, Bar:

 class Bar { public: void frob(); }; 

Now you declare the Foo class:

 class Foo; 

All you can do with Foo is create a pointer to it. Now suppose that you added information that Foo obtained from Bar :

 class Foo: public Bar; 

What can you do now that you could not do before? I think all you can do is take a pointer to Foo and put it in a pointer to Bar , and then use that pointer.

 void frob(Foo* f) { Bar *b = (Bar)f; b->frob(); } 

However, you had to generate a pointer elsewhere, so that you could just accept a pointer to Bar .

 void frob(Bar* b) { b->frob(); } 
+1
Feb 02 '10 at 11:22
source share