Link to home
Start Free TrialLog in
Avatar of avl
avl

asked on

forward-declare class B as being derived from class A

I want to do something, like:
 class B : public A;
That is: I want to forward-declare Type B, but
let the compiler know, that B is derived from A.
However, the Compiler (or even C++-spec)
doesn't seem to accept this.

The reason, I'd need it is:
  In some part of my prog, I'm using only
  pointers to these classes, and I want to pass
  a B* to a method that takes a  const A*  
  (without casting, and without #include'ing
  the real definition of B)
Sounds not too far off, does it ?

The Compiler I need it for (if that should make
 a difference) is SUN's Forte WS6U2.

This question is quite important to me, therefore
I won't accept simple "won't go"-answers unless
they also point out, *why* this would be impossible or
what trouble this would inevitably put me into.
Avatar of jkr
jkr
Flag of Germany image

>>forward-declare class B as being derived from class A

That's not possible. (If you need a "why", consult your compiler error message :o)

But what you want to do is not uncommon - use interfaces to accomplish that:

#define interface struct

interface IDemo {

virtual void Method1 ( int, int) = 0;
virtual void Method2 ( ) = 0;
};

class CDemo: public IDemo {

CDemo () {}
~CDemo () {}

virtual void Method1 ( int, int) { /* ... */ };
virtual void Method2 ( )  { /* ... */ };

};

and pass a pointer to CDemo to functions that expect a IDemo* - that's the common way to do that...
Avatar of avl
avl

ASKER

>>forward-declare class B as being derived from class A
>That's not possible. (If you need a "why", consult your
>compiler error message :o)

The compiler just told me a parse-error:  Not very
enlightening. (Do other Compilers give more informative
feedback ?)

In your example you actually *define* class CDemo,
which is not what I was after.

I wanted either an explanation, why my wish was
unfulfillable, or (if one exists) the syntax of how I can
make it work.

There is a bit more to the classes than I wrote in the
question:
The whole class-hierarchy is already setup, and cannot
be changed anymore. (Thus, I can't insert any "dummy"
classes).
Actually, my goal was to avoid #include'ing the class-
header-files into some of the cpp-files, to reduce the
number of dependencies.
>>In your example you actually *define* class CDemo

Well, at some point, you do need a declaration/implementation.

You'd use it like

void SomeFunc ( IDemo* p);

CDemo cd;

SomeFunc ( &cd);
Avatar of avl

ASKER

No, without passing through the definition of CDemo,
 (which is, say, defined in cdemo.hpp, which again
  includes  idemo.hpp and lots of other necessary(!)
  stuff, that all in all results in a slow compile)
the C++-compiler would even barf on:
   void SomeFunc ( const IDemo* p);
   CDemo* someOtherFunc();
   CDemo *cd = someOtherFunc();
   SomeFunc (cd);  <-- no matching function found.
because then the compiler doesn't know, that
CDemo is a SubClass of  IDemo.

If it were not for the relationship between
 IDemo and CDemo, I would be all fine, just
 forward-declaring CDemo and IDemo.
E.g..: If SomeProc() were declared with a CDemo* or
 if my local pointer variable was a IDemo, I would not
 need to include cdemo.hpp.

I don't want to include cdemo.hpp, but still let the
compiler know, that CDemo is a SubClass of IDemo.
("cdemo.hpp" is still included into other cpp-files, e.g.:
where someFunc(),someOtherFunc(),... are implemented.)

Is my problem clear now ?
>>Is my problem clear now ?
Not really.  :-)

If class 'B' derives from class 'A', then in order to compile class 'B' you have to include the declaration for class 'A'.
And in order to compile any implementation that is using class 'B', you would have to include the declaration for class 'A'.

I'm not sure if that's what you're trying to do, but if so, there's no way around that.  The compiler needs access to the base class declaration in order to compile a derive class implementation.
>>The compiler needs access to the base class declaration

Yup - that's why I suggested an interface...
Avatar of avl

ASKER

No,  but we're coming nearer, hopefully  :-)

First of all, I'm not a C++ newbie.  I know certainly well,
when I really need a fully defined class, and where an
incompletely defined (== forward-declared) class
suffices.

It is clear, that when I really use the internals (methods,...) of class B (the derived one), I absolutely undoubtedly
need fully declared class B and A.

I'm talking about a piece of code, that may be the content
of a single cpp-file, which does NOT use the internals
of neither A nor B, but only passes around pointers to
these classes.

passing around pointers is usually something, where
forward-declared classes fully suffice.

BUT, I also want to cast pointers.  And for this I'd
need to tell the compiler somehow the following:
"I don't care, what class A and class B really look
like, but B will be declared somewhere else as being
derived from A, so a pointer to B should be implicitly
cast-able to a pointer to A, as it would, if you knew
the internals of these classes now."

I just want to tell the compiler that pointers to
B are one-way-compatible to pointers to A.

I've experienced already, that my first attempt
(class B : class A;  <-- attempted forward declaration
of B with little extra information) failed with a parse-error,
thus very likely is not valid C++ for now.

And now I'm out for insight on why this has not been
recognized as useful and added to C++-language,
or some other way, to make A* and B* compatible,
but not including the complete declaration of
them, and neither doing fake-declaration of B.
(A would even be available in my case)
Well, that is something (if I am still with you :o) that can be done using a 'dynamic_cast()' - however, in order for this to work, the compiler needs to have 'seen' the declaration at some time.

What you could always do is uind C-style casts...
>>And now I'm out for insight on why this has not been
>>recognized as useful and added to C++-language,
You can accomplish this in C++.  It's called a proxy class.
A proxy class will allow you to use a class without having to have access to the target class header.

That is the only way you're going to be able to hide the base class header class.

It really makes no sense to tell an implementation that B is derived from A, without telling it what A looks like.
Even if you could magically get the compiler to see B as derived from A (without declaration), the compiler wouldn't be able to put that information to any use,
 since the compliler wouldn't know what data type 'A' has, or what member functions 'A' has.
What use would that be?


Since this type of code would be ambiguous, it would not be added to the C++ language.
First, it sounds like the only reason you want to do all of this is to avoid having the compiler read a particular header file.  If so, you must have a very slow compiler, or one that does not implement precompiled headers.  Get some good tools.

But more importantly, the question makes no sense.  The reason you might need to know that B is derived from A is that at some point you plan on doing something like:

     m_pcB->DoThatFnThatsInBbutNotInA(TRUE);

And the only way you could even think of doing that is if the class B had been defined somewhere.

Otherwise, if you are only going to use members of A, then why not just declare it as a pointer-to-class-A?  This is very common.  For instance, a function expects a CDialog* but a CWnd* can easily be passed around until such time as you need to use the specialized members of CDialog.  At that time you just cast it to the derived class.

If I missunderstand, then please post a few lines of code that illustrate and example of what you are trying to do and why it is not working.

-- Dan
ASKER CERTIFIED SOLUTION
Avatar of ambience
ambience
Flag of Pakistan image

Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
>> And now I'm out for insight on why this has not been
recognized as useful and added to C++-language,

Do you still think so ?
Avatar of avl

ASKER

Now, that is the type of answer, what I had hoped for,
(even though a positive answer would have made me
happier.)

I didn't know, that such an implicit cast has that much magic
involved, but now that you wrote it, it is clear, why what I
wanted is principially unfulfillable.

Sorry for the others, who spent their time on this thread,
but only ambience hit the nail on its head.