Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

const semantics for database or filesystem access

Tags:

c++

constants

I regularly use const when working with in-memory data structures and keep my code const-correct, but I'm not sure how const should apply to more complex objects, such as the following:

  • objects representing connections to remote systems
  • objects backed by a database (that may load parts from the database on demand)
  • objects backed by an on-disk directory tree (with access to the directory tree controlled by a separate object hierarchy)

What should const methods signify for objects like these? I can think of a couple of possibilities:

  • "strict" const - Methods which don't modify any in-memory state are const. However, this would seem to break encapsulation, since it would require callers to know which methods modify the connection state and which don't.
  • "logical" const - Methods which don't modify the logical state of the object are const. However, this would potentially require marking a lot of state and caching variables as mutable. Although I realize that's what mutable is designed for, using it this much feels like a hack. Also, given that const means "I promise not to modify this," it doesn't seem right to apply it when methods may modify the state of the connection in strange and wonderful ways (as long as they maintain encapsulation), cache results as much as they want, throw exceptions if the connection fails, etc.
  • No const - In light of the preceding problems, does const simply not have much meaning for more complicated objects?

Which approach is most useful? Which is most common?

like image 618
Josh Kelley Avatar asked Jan 11 '12 14:01

Josh Kelley


1 Answers

This is a difficult question. I'm actually working on the same thing right now. I have a large in-memory data structure backed by a MySQL database. I started with a "const wherever possible" approach, but that turns out to be not very often in practice:

  • You might be using a 3rd-party library that isn't const-correct.
  • Not all SELECT statements are actually read-only. For example, SELECT GET_LOCK definitely modifies state on the db side.
  • I haven't met many C++ programmers who can use mutable properly. I certainly don't have much experience with it. Future maintainers might cause more problems than mutable would solve. You know your team best, so it's up to you whether you'd want to go that route.

I think a const object with a single mutable handle to the database might be the most elegant solution. Decide what a const object should reasonably be able to do, and make all those functions const. Users of your class only need to know which functions are const and which aren't. The header file will give them that. They shouldn't need to know why a particular function is const or non-const. I do agree though that a pile of mutable members starts to look hackish.

In my case, I basically had to give up on const-correctness. A const object would've been so handcuffed that it couldn't do anything useful. Based on my years of experience, I suspect this is what usually happens in practice. Logical const-correctness is a nice ideal (and you should definitely start there if you're building from scratch), but when it comes to real, shipping code, no const is the way to go.

like image 89
Michael Kristofik Avatar answered Sep 27 '22 18:09

Michael Kristofik