Solved

forward-declare class B as being derived from class A

Posted on 2002-04-19
13
329 Views
Last Modified: 2011-08-18
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.
0
Comment
Question by:avl
  • 4
  • 4
  • 2
  • +2
13 Comments
 
LVL 86

Expert Comment

by:jkr
ID: 6953597
>>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...
0
 

Author Comment

by:avl
ID: 6953760
>>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.
0
 
LVL 86

Expert Comment

by:jkr
ID: 6953797
>>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);
0
 

Author Comment

by:avl
ID: 6953940
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 ?
0
 
LVL 30

Expert Comment

by:Axter
ID: 6954209
>>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.
0
 
LVL 86

Expert Comment

by:jkr
ID: 6954222
>>The compiler needs access to the base class declaration

Yup - that's why I suggested an interface...
0
Is Your Active Directory as Secure as You Think?

More than 75% of all records are compromised because of the loss or theft of a privileged credential. Experts have been exploring Active Directory infrastructure to identify key threats and establish best practices for keeping data safe. Attend this month’s webinar to learn more.

 

Author Comment

by:avl
ID: 6954279
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)
0
 
LVL 86

Expert Comment

by:jkr
ID: 6954298
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...
0
 
LVL 30

Expert Comment

by:Axter
ID: 6955116
>>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.
0
 
LVL 49

Expert Comment

by:DanRollins
ID: 6958402
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
0
 
LVL 22

Accepted Solution

by:
ambience earned 300 total points
ID: 6959217
>> 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."

so much already said, you may not care what A and B are , and that you may know B derives from A, so it can be "implicitly casted to pointer to A". But you see that compiler doesnt know that.

And what you call IMPLICIT casting , on part of the compiler is infact some arithmetic that depends upons the layout of both A and B. The compiler has to deal with the memory layout of B so that to be able to cast that to A.

possibly the compiler adds an "+/-offset" to the pointer to B and interprets the resulting value as a poointer to A.

And the value of that offset depends upon the internals of A i.e. members and aggregates inside A or B affect the offset. And things get real complicated with virtual inheritence.

If this doesnt make sense , think about the case of multiple inheritence. And that is why you need the declaration of both A and B, at the time of implicit conversions.

Hope this helps, correct me if i am wrong.

0
 
LVL 22

Expert Comment

by:ambience
ID: 6959238
>> 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 ?
0
 

Author Comment

by:avl
ID: 6959257
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.
0

Featured Post

Is Your Active Directory as Secure as You Think?

More than 75% of all records are compromised because of the loss or theft of a privileged credential. Experts have been exploring Active Directory infrastructure to identify key threats and establish best practices for keeping data safe. Attend this month’s webinar to learn more.

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

Suggested Solutions

Title # Comments Views Activity
C++ - Convert a wString to char * 9 496
How to convert MFC APP to Win32 APP. 19 68
C++ question 3 60
C++ mouse_event mouse look 7 64
When writing generic code, using template meta-programming techniques, it is sometimes useful to know if a type is convertible to another type. A good example of when this might be is if you are writing diagnostic instrumentation for code to generat…
Container Orchestration platforms empower organizations to scale their apps at an exceptional rate. This is the reason numerous innovation-driven companies are moving apps to an appropriated datacenter wide platform that empowers them to scale at a …
The viewer will learn how to user default arguments when defining functions. This method of defining functions will be contrasted with the non-default-argument of defining functions.
The viewer will learn additional member functions of the vector class. Specifically, the capacity and swap member functions will be introduced.

948 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question

Need Help in Real-Time?

Connect with top rated Experts

19 Experts available now in Live!

Get 1:1 Help Now