Professors hammered it into my head when I was in school, associates have jumped down my throat for it on code reviews, and it's in pretty much every C++ textbook out there: "accessor" (aka "selector" or "getter") methods must be marked const
. If it doesn't change or mutate the data, then mark it const
.
Why? How could the invocation of an accessor modify the private data?
In the following example, I have set up a simple class and one accessor. How can getBrand()
be used to modify the private data? In my eyes, it can't; so why do we need to mark it const
?
In other words, am I correct in saying that it is impossible for getBrand()
to be used, in practice, to mutate a private property?
Example:
#include <iostream>
#include <string>
class Cheese {
public:
Cheese(std::string brand):brand_(brand) {}
std::string getBrand() { return brand_; } // Intentionally not marked const
private:
std::string brand_;
};
int main() {
Cheese cheddar("Cabot clothbound");
std::cout << "Brand: " << cheddar.getBrand() << std::endl;
return 0;
}
It's actually very simple: If the method is not const, you would not be able to use it on const
objects - but you do want to be able to use it. With your class, you can't implement
void print_brand(const Cheese& cheese);
(unless you const-cast, which you shouldn't do).
Also, if you do make it const, instead of returning a copy of your string - which may or may not get optimized away, you could implement:
const std::string& getBrand() const { return brand_; }
which returns a reference, or perhaps
std::string_view getBrand() const { return brand_; }
that does not "commit" your API to the string class (read about string_view
here; it was only officially added to the language in C++17, but is available as std::experimental::string_view
with recent compilers).
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With