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; }
};
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; }
};