I'm writing a class that wraps a legacy C API that controls a hardware device. In a simplified example, I might have something like:
class device
{
public:
void set_request(int data) { legacy_set_req(p_device, data); }
int get_response() const { return legacy_get_r开发者_如何学Pythonsp(p_device); }
private:
device_handle_t *const p_device;
};
The class itself has no bitwise state; therefore, I could choose to declare set_request()
as const
, and the compiler would be happy with that. However, from a semantic point-of-view, would this be the correct approach, given that it affects the observable behaviour of the object? (i.e. the encapsulated hardware device very much does have state.)
I believe that const
should reflect logical const-ness, regardless of the internal representation. Just because your object contains only a pointer to something that changes, doesn't mean all your member functions should be const
.
C++ even has the mutable
concept for internal representation that needs to change even if conceptually the object does not. The const
keyword is clearly not intended to represent "bitwise" const-ness.
If it changes the state, it generally should not be const
. The fact that the state in question is owned remotely (i.e., in a controlled device) doesn't change that.
A useful test is:
could code with only const
access to the device instance interfere with the operation of code with non-const
access
Basically, const
access is meant to mean you're effectively an observer. Here, it looks as though code calling set_request(...)
at time T1 then get_response()
at time T3 would be seriously screwed if some supposed observer called set_request()
with different parameters at time T2. For that reason, set_request(...)
shouldn't be accessible to observers - it should be non-const
.
(There are caveats to the test - e.g. if a const
"observer" needs a lock it can obviously affect non-const
usage from another thread from a timing perspective but shouldn't do so from a functional one - but it's pretty obvious how to factor that into your analysis).
Like other type and member qualifications (e.g., public, private, virtual), const expresses both intention and the language semantics (i.e., safety features) that support that intention. In this case, the intention would appear counter-intuitive, even if the underlying semantics would be safe. I wouldn't do it.
精彩评论