Casting to base class

M

Marcos Boyington

Hey guys, quick question about how C++ designers chose to not implement
this, I'm sure there are some people here who can take a better guess at it
than I.

So, in C++, the only way to prevent typecasting to a base class is by having
private inheritance (correct?). However, this prevents one from doing 2
very important things:

Example #1: Allow conversion from child -> grandparent, but NOT child ->
parent.

Say we have a class structure such as this:
class AbstractionLayer
{};
class FunctionalityLayer : protectected AbstractionLayer
{};
template <typename _T>
class TypesafeLayer : private FunctionalityLayer
{};

We want to be able to cast to AbstractionLayer, but not to
FunctionalityLayer (this is an internal class which has funcitonality, but
we don't want usage of this class directly). However, we do want to
typecast to an AbstractionLayer.

Take, for example, a memory allocator. AbstractionLayer provides simple
allocation of memory, returning simply allocated memory and freeing
allocated memory. FunctionalityLayer provides the actual allocation of
memory: we could have, say, 2 types, a static allocator (allocates one big
chunk and asserts if we try to insert memory when it's full), and a growing
allocator (creates a linked list of memory chunks). Lastly, TypesafeLayer
would have 2 functions which are typesafe, and would do the appropriate
new() and ~ calls after allocating/deallocating memory. However, in the
example above, we are not allowed to typecast to AbstractionLayer.

Example #2: Limit typecasting but allow function usage

Say we have something similar to the above, i.e. a class with functionality.
We want these functions to be externally accessible to others, HOWEVER, we
do NOT want it to be typecasted to the base class. Sure we can do "using"
for all the functions, but this becomes a hassle if we add functionality, as
we have to modify both classes. Lastly, in a case such as this, we are left
with no options:

class FunctionalityLayer1 : protectected AbstractionLayer
{};
class FunctionalityLayer2 : protectected AbstractionLayer
{};
template <typename _FuncLayer>
class TypesafeLayer : private _FuncLayer
{};

Anyone know if they're planning to add support to overriding the "conversion
to a reference to a base class operator", or why it hasn't been done yet?
The above examples are shown below with this operator, if C++ were to
support this (it does not):

Example #1:
class AbstractionLayer
{};
class FunctionalityLayer : protectected AbstractionLayer
{};
template <typename _T>
class TypesafeLayer : private FunctionalityLayer
{
public:
operator AbstractionLayer& () { return *this; }
};

Example #2:
class FunctionalityLayer1 : protectected AbstractionLayer
{};
class FunctionalityLayer2 : protectected AbstractionLayer
{};
template <typename _FuncLayer>
class TypesafeLayer : private _FuncLayer
{
private:
operator _FuncLayer& () { return *this; }
};
 
J

Jonathan Mcdougall

Marcos said:
Hey guys, quick question about how C++ designers chose to not implement
this, I'm sure there are some people here who can take a better guess at it
than I.

So, in C++, the only way to prevent typecasting to a base class is by having
private

and protected
inheritance (correct?). However, this prevents one from doing 2
very important things:

Example #1: Allow conversion from child -> grandparent, but NOT child ->
parent.

Say we have a class structure such as this:
class AbstractionLayer
{};
class FunctionalityLayer : protectected AbstractionLayer
{};
template <typename _T>
class TypesafeLayer : private FunctionalityLayer
{};

We want to be able to cast to AbstractionLayer, but not to
FunctionalityLayer (this is an internal class which has funcitonality, but
we don't want usage of this class directly). However, we do want to
typecast to an AbstractionLayer.

template <class T>
class TypesafeLayer : public AbstractionLayer,
private FunctionalityLayer
{
};
Example #2: Limit typecasting but allow function usage

Say we have something similar to the above, i.e. a class with functionality.
We want these functions to be externally accessible to others, HOWEVER, we
do NOT want it to be typecasted to the base class. Sure we can do "using"
for all the functions, but this becomes a hassle if we add functionality, as
we have to modify both classes.

Either A is a B or A is not a B. You cannot have both so you're stuck
with using declarations or function forwarding. Your design seems to be
flawed somehow.
Lastly, in a case such as this, we are left
with no options:

class FunctionalityLayer1 : protectected AbstractionLayer
{};
class FunctionalityLayer2 : protectected AbstractionLayer
{};
template <typename _FuncLayer>
class TypesafeLayer : private _FuncLayer
{};

That's too bad, and that's another indication that your design is
impraticable.
Anyone know if they're planning to add support to overriding the "conversion
to a reference to a base class operator", or why it hasn't been done yet?
The above examples are shown below with this operator, if C++ were to
support this (it does not):

Example #1:
class AbstractionLayer
{};
class FunctionalityLayer : protectected AbstractionLayer
{};
template <typename _T>
class TypesafeLayer : private FunctionalityLayer
{
public:
operator AbstractionLayer& () { return *this; }
};

Example #2:
class FunctionalityLayer1 : protectected AbstractionLayer
{};
class FunctionalityLayer2 : protectected AbstractionLayer
{};
template <typename _FuncLayer>
class TypesafeLayer : private _FuncLayer
{
private:
operator _FuncLayer& () { return *this; }
};

These should be illegal: TypesafeLayer is neither a FunctionalityLayer
nor a _FuncLayer, it is implemented in terms of these. It is a *good*
thing such construct is disallowed.

The whole thing seems to be caused my a misunderstanding/misuse of
public inheritance.


Jonathan
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,995
Messages
2,570,230
Members
46,820
Latest member
GilbertoA5

Latest Threads

Top