Topic: Const inheritance
Author: daryl.vandenbrink@maptek.com.au
Date: Fri, 12 Oct 2012 18:23:10 CST
Raw View
[ moderator's note: Please do not quote more of the original message than is necessary. ]
I don't have an answer to your question, except to say that unfortunately, const inheritance is not allowed. I don't know why. I too would like const inheritance, so that I can do something like the following:
class Object
{
public:
// Constructor for object creation
Object();
// Constructor for object locking.
Object(const LockingParameters& LP);
// const methods
// non-const methods
};
template<class T>
class LockR : public const T
{
LockR(ObjectHandle Handle);
}
template<class T>
class LockRW : public T
{
LockRW(ObjectHandle Handle);
}
Let me explain: Object (and classes that inherit from it) is a wrapper class that accesses data in a shared memory-mapped file. It needs to use locking to manage access to these objects. Const methods are used for reading, while non-const methods are used for writing. The first constructor of the Object class is used for persistent object creation (the destructor does not destroy the persistent object, it merely unlocks it). The second constructor is used for locking existing objects. However, the LockingParameters class is hidden and only the LockR and LockRW template classes can access it. This is to ensure that nobody can use read-locking parameters in the constructor then proceed to call non-const methods, which would cause corruption. This would all work nicely if LockR could inherit from a const class, but alas it can't, so I must hack around this limitation in the C++ standard by using an internal const object and overloading operator-> to make LockR behave like a poi
n
ter to an Object instead of like an actual Object. This does not look as nice and is not quite as easy to use.
On Sunday, September 6, 2009 2:40:27 AM UTC+9:30, tohava wrote:
> What I would like to do:
> Given a class A, I wish to do something like this:
> class B : public const A
> {...}
> (Note: the public is only one case, it should also be possible for
> private/protected).
>
> What does it mean:
> Basically, what inheritance means is: I want my class to have a hidden
> object field of type A, and that syntactically, every attempt to
> access a member that is not in B will be redirected to a field of the
> hidden object. There is one problem here, the hidden object field
> cannot be constant. Constant inheritance should enable us to do that.
> In the case of constant inheritance, the compiler will try to redirect
> the member access only if it is a member access that does not violate
> the constness of the hidden object field (i.e. not allowed to access
> non-const methods, not allowed to change variables that aren't mutable
> except for through the constructor of A). In case the constness of the
> hidden object is violated, the compiler will emit a proper error
> message.
>
> A practical use case that required this (simplified):
> Assume we have the following class:
> struct Rect
> {
> int width, height;
> int left, top;
> }
> Indeed, somebody messed up, and the class Rect contains public fields.
> However, now is it is too late (it could also be because I'm using
> something that was defined in old C code). Anyhow, I would like to
> define a class which inherits from Rect and represents a Square (Thus,
> I add the requirement that height == width, while wanting to preserve
> the original Rect interface as much as possible). A complicated
> solution would be to somehow inherit from Rect and add this
> requirement, but I feel this is too specific. A more general solution
> (but less good) would be to limit myself to working with an immutable
> square class (in my case it was enough as there were few changes which
> were done via copy constructors), this looks as follows:
>
> class ImmutableSquare : public const Rect
> {
> private:
> Rect ConstructRect(int left, int top, int size)
> {
> Rect r;
> r.left = left; r.top = top; r.width = r.height = size;
> return r;
> }
> public:
> ImmutableSquare(int left, int top, int size) :
> Rect((ConstructRect(left, top, size))
> {}
> }
>
> This class gives me Square objects with a Rect interface.
>
> Interesting theoretical view point:
> We look at the following two definitions:
> class A {...}
> typedef const A B;
>
> While the first definition defines a class, the second one defines a
> type. In fact, we can look at what I offer here as a new view of
> constness, as something that creates a new class from an existing one.
> One can think of "const A" as a new class, which inherits (privately,
> not public/protected) from the class A, and blocks constness-breaking
> member access for anyone
> except it's constructor. One can argue regarding how this interacts
> with abstractness, but I feel it would be the simplest to say that if
> A is abstract, then so is const A, and the only way to get rid of this
> abstractness is to implement the abstract methods. A tricky point
> would be abstract methods which violate constness, and I feel the way
> it should be handled is not to allow inheriting from a const class
> which contains abstract constness-breaking methods.
>
> Questions;
> Is it possible to have a class which inherits both from A and const A,
> if so, how do we differentiate between members? B::const A::x doesn't
> look so well.
>
> Is it possible to somehow extend this to new kinds of inheritance
> which are based on other field properties? static? volatile? thread-
> local (in case the standard adds it)?
--
[ comp.std.c++ is moderated. To submit articles, try posting with your ]
[ newsreader. If that fails, use mailto:std-cpp-submit@vandevoorde.com ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://www.comeaucomputing.com/csc/faq.html ]
Author: tohava <tohava@gmail.com>
Date: Sat, 5 Sep 2009 11:10:27 CST Raw View
What I would like to do:
Given a class A, I wish to do something like this:
class B : public const A
{...}
(Note: the public is only one case, it should also be possible for
private/protected).
What does it mean:
Basically, what inheritance means is: I want my class to have a hidden
object field of type A, and that syntactically, every attempt to
access a member that is not in B will be redirected to a field of the
hidden object. There is one problem here, the hidden object field
cannot be constant. Constant inheritance should enable us to do that.
In the case of constant inheritance, the compiler will try to redirect
the member access only if it is a member access that does not violate
the constness of the hidden object field (i.e. not allowed to access
non-const methods, not allowed to change variables that aren't mutable
except for through the constructor of A). In case the constness of the
hidden object is violated, the compiler will emit a proper error
message.
A practical use case that required this (simplified):
Assume we have the following class:
struct Rect
{
int width, height;
int left, top;
}
Indeed, somebody messed up, and the class Rect contains public fields.
However, now is it is too late (it could also be because I'm using
something that was defined in old C code). Anyhow, I would like to
define a class which inherits from Rect and represents a Square (Thus,
I add the requirement that height == width, while wanting to preserve
the original Rect interface as much as possible). A complicated
solution would be to somehow inherit from Rect and add this
requirement, but I feel this is too specific. A more general solution
(but less good) would be to limit myself to working with an immutable
square class (in my case it was enough as there were few changes which
were done via copy constructors), this looks as follows:
class ImmutableSquare : public const Rect
{
private:
Rect ConstructRect(int left, int top, int size)
{
Rect r;
r.left = left; r.top = top; r.width = r.height = size;
return r;
}
public:
ImmutableSquare(int left, int top, int size) :
Rect((ConstructRect(left, top, size))
{}
}
This class gives me Square objects with a Rect interface.
Interesting theoretical view point:
We look at the following two definitions:
class A {...}
typedef const A B;
While the first definition defines a class, the second one defines a
type. In fact, we can look at what I offer here as a new view of
constness, as something that creates a new class from an existing one.
One can think of "const A" as a new class, which inherits (privately,
not public/protected) from the class A, and blocks constness-breaking
member access for anyone
except it's constructor. One can argue regarding how this interacts
with abstractness, but I feel it would be the simplest to say that if
A is abstract, then so is const A, and the only way to get rid of this
abstractness is to implement the abstract methods. A tricky point
would be abstract methods which violate constness, and I feel the way
it should be handled is not to allow inheriting from a const class
which contains abstract constness-breaking methods.
Questions;
Is it possible to have a class which inherits both from A and const A,
if so, how do we differentiate between members? B::const A::x doesn't
look so well.
Is it possible to somehow extend this to new kinds of inheritance
which are based on other field properties? static? volatile? thread-
local (in case the standard adds it)?
--
[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@netlab.cs.rpi.edu]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://www.comeaucomputing.com/csc/faq.html ]