logical const and event programming

L

LuB

I'm writing a Win32 application - and more specifically, doing event
programming.

I want the application to be const compliant but I'm faced with a bit
of a conundrum.

Physically, many of my window methods can indeed be const Why? Many
Win32 calls send msg to a WNDPROC - or event handler. Therefore, a
const method may actually change something about a window. The 'value'
of const is lost here.

For example, to move a window - one can call ::SetPosition(hwnd, ...).
Assuming hwnd_ is a private instance member, If I wrap that call in a
class method, would I write

void SetPosition(...) const
{
::SetPosition(hwnd_, ...);
}

or

void SetPosition(...)
{
::SetPosition(hwnd_, ...);
}

Either would work. Logically, its not really a const method since its
changing a property of the window - namely, its position. But
physically, it can be labelled as const because of the inherent
indirection in event programming.

The answer must applicable/general enough to handle/work with _any_
message.

Just curious what the consensus is.

Thanks,

-Luther
 
V

Victor Bazarov

LuB said:
I'm writing a Win32 application - and more specifically, doing event
programming.

I want the application to be const compliant but I'm faced with a bit
of a conundrum.

Physically, many of my window methods can indeed be const Why? Many
Win32 calls send msg to a WNDPROC - or event handler. Therefore, a
const method may actually change something about a window. The 'value'
of const is lost here.

For example, to move a window - one can call ::SetPosition(hwnd, ...).
Assuming hwnd_ is a private instance member, If I wrap that call in a
class method, would I write

void SetPosition(...) const
{
::SetPosition(hwnd_, ...);
}

or

void SetPosition(...)
{
::SetPosition(hwnd_, ...);
}

Either would work. Logically, its not really a const method since its
changing a property of the window - namely, its position. But
physically, it can be labelled as const because of the inherent
indirection in event programming.

The answer must applicable/general enough to handle/work with _any_
message.

Just curious what the consensus is.

To be honest, I don't know what the consensus is. Most likely, if your
'SetPosition' is a member (and only a member can be const, right?), you
only need to make it non-const if it does indeed change the _object_
for which it's called. Now, in your example 'SetPosition' is a very
thin wrapper over an OS API call. That's your choice. In real life,
perhaps it would make sense to cache the size information in the object
(so you don't have to bother the OS when you need to know the position
of the window, for example). If that's the design, then setting the
position of a window will require that the member is non-const because
it's going to update some members.

Another consideration is the appearance of the design. You can choose
to designate certain member functions non-const _simply_because_ they
are logically such. That should allow you to impose some strictness on
your own programming style when 'SetPosition' cannot be called from,
say, 'GetText' (a contrived example, I concede, but sufficient).

Generally, it's up to you. Common sense should be your guide here.

V
 
A

Alf P. Steinbach

* LuB:
I'm writing a Win32 application - and more specifically, doing event
programming.

I want the application to be const compliant but I'm faced with a bit
of a conundrum.

Physically, many of my window methods can indeed be const Why? Many
Win32 calls send msg to a WNDPROC - or event handler. Therefore, a
const method may actually change something about a window. The 'value'
of const is lost here.

For example, to move a window - one can call ::SetPosition(hwnd, ...).
Assuming hwnd_ is a private instance member, If I wrap that call in a
class method, would I write

void SetPosition(...) const
{
::SetPosition(hwnd_, ...);
}

or

void SetPosition(...)
{
::SetPosition(hwnd_, ...);
}

Either would work. Logically, its not really a const method since its
changing a property of the window - namely, its position. But
physically, it can be labelled as const because of the inherent
indirection in event programming.

The answer must applicable/general enough to handle/work with _any_
message.

Just curious what the consensus is.

I don't know about the consensus, but constness is a tool that's part of
a larger toolset, and is only meaningful when those other tools are also
applied. For example, having

void setPosition( Position pos ) { ... }

implies also having

Position position() const { ... }

where having setPosition() non-const is so that the client code can be
assured it won't mess around with a window it has declared const, while
having position() const is so that the client code can obtain the
position of a window it has declared const. It does not matter that
setPosition can be implemented as a C++-level const function. Because
it can /always/ be implemented technically as a C++-level const
function, that has nothing to do with event programming, e.g.

// How to absolutely not to do things... ;-)
class Window
{
private:
int* myXPos;
public:
Window(): myXPos( new int(666) ) {}
~Window() { delete myXPos; }

void setX( int x ) const { *myXPos = x; } // Uhuh, 'const'!

int x() { return *myXPos; } // Double uhuh, no 'const'!
};

Here all is well as long as the client code doesn't declare a Window as
const. But if the client code does, it finds that it can change the
Window's x-position (hey, wasn't that what 'const' should help guard
against?), and that it can't obtain the current x-position (hey,
shouldn't that be possible regardless of 'const' or not?). So to
support natural expectations for 'const', making 'const' a practically
useful tool for the client code, do the opposite of the above.
 
L

LuB

I hope google doesn't top post .... but thanks to both of you for your
suggestions.

To follow up, one more scenerio rears its head at times. I am wondering
if this usage falls outside the conceptual tools Alf speaks of when
using const. (The underlying reasons for my questions - is because I
generally write everything const correct unless I have to change it -
so everything is const unless it cannot be). On that note, I'm sure
that in the right hands, the immutable keyword can be used where
appropriate - while in the wrong hands, it can be terribly abused,
confusing and incorrect.

Lets assume I want to paint something everytime a window is resized. I
have a class thinly wrapping a window and its related functionality.
Lets say the windows OnPaint handler member method is about 75 lines
long. In general, the OnPaint method asks its children for their
dimensions (const correctly) and then paints them. Generally, the
window doesn't maintain any state in this method ... but there just so
happens to be one measurment that the parent window *does* need to keep
track of. In this case, its the placement of an invisible splitter.
Lets just say that the splitter's position changes everytime the window
is resized - but otherwise, everything stays the same in this fairly
lengthy method.

I am opting to make this member _mutable_ and the OnPaint method const.

It seems that this is harmless and lets me call OnPaint from any const
windows - which I make it a practice to use as often as possible. It
seems I've judged that there is _important_ state like attached
children windows and less important state like where a splitter gets
pushed around to and furthermore, the less important state (or
incidental state) can be declared mutable when it seems harmless to do
so.

Would this practice be frowned upon in a commerical product? I would
intuit that using mutable should be done very infrequently - but is
fine when appropriate.

Thanks again,

-Luther
 

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,769
Messages
2,569,579
Members
45,053
Latest member
BrodieSola

Latest Threads

Top