Const Functions and Interfaces in C++ - c++

I'll use the following (trivial) interface as an example:
struct IObject
{
virtual ~IObject() {}
virtual std::string GetName() const = 0;
virtual void ChangeState() = 0;
};
Logic dictates that GetName should be a const member function while ChangeState shouldn't.
All code that I've seen so far doesn't follow this logic, though. That is, GetName in the example above wouldn't be marked as a const member function.
Is this laziness/carelessness or is there a legitimate reason for this? What are the major cons of me forcing my clients to implement const member functions when they are logically called for?
EDIT: Thanks for your responses everyone. I think it's pretty much unanimous: laziness/ignorance is the reason for what I'm seeing.

I think it's laziness/carelessness. GetName() should have no effect on the object's state, and the contract of IObject should state that fact explicitly.
If the inheriting class was somehow forced to make GetName() have (hidden!) side effects, they could always declare the corresponding fields as mutable.

Is this laziness/carelessness or is there a legitimate reason for this?
The former. If you really haven't seen any code which does this right, get a new job immediately.
What are the major cons of me forcing my clients to implement constmember functions when they are logically called for?
It allows the compiler to discover common bugs at compile-time. (Nothing better than errors discovered at compile-time. Everything that fails on your desk, won't fail at the client's site.)
More than ten years ago, shortly after I joined a new company and got to hacking at one of their projects, I found that a method that should have been const wasn't, preventing some of my const-correct code to compile. I considered just casting my const away and get on, but I couldn't myself bring to do this.
So I made the method const - just to discover that it called other methods, which should have been const, too, but weren't either. So I changed them as well - just to discover...
In the end, I spent several days hunting through all of the project, adding const left and right.
Co-workers laughed at me - until I showed them some of the bugs the compiler had discovered due to me adding const. Interestingly, a few long-standing bugs nobody had ever taken the time to thoroughly investigate were not reproducible anymore either, after that.

While I think the "laziness" answer is probably right in your case, I do just want to make the point that sometimes a single const keyword is not expressive enough to capture the details of mutability of your class.
Consider:
class MyClass {
public:
bool operator==(const MyClass &other) const {
return identity == other.identity;
}
void setVisible(bool vis) { gfx.setVisible(vis); }
bool isVisible() const;
// other methods ...
private:
string identity;
GraphicsData gfx;
}
I think this code is reasonable:
MyClass item = ...
item.setVisible(true);
// I want to call a function and be sure that the object's
// visibility did not change, so pass a const ref.
const MyClass &constRef = item;
someSafeFunction(constRef);
But at the same time, I think this code is reasonable, too:
// Imagine an appropriate std::hash<MyClass> has been
// defined, based on MyClass::identity.
unordered_set<MyClass> set = ...
// Hide some items
for (MyClass &item : set) {
item.setVisible(false);
}
However, that second bit of code will not compile, because unordered_set can only give const references to its contents (live example).
This is because a modification to the object could change its hash code, invalidating its location in the container.
So in effect, unordered_set demands that operator== and const are referring to the same notion of identity.
But that's not what we want in our first use case.
The problem is that our code has two notions of "did the object change", which both make sense from different points of view.
But there is only one const keyword you can apply, so you have to pick one, and the other case will suffer.

Related

C++ Get/Set accessors - how do I avoid typing repetitive code?

I'm writing a pretty large library, and I find myself writing almost identical accessors all the time. I already have several dozen accessors such as the one below.
Question: How can I declare/implement accessors to save typing all this repetitive code? (No #defines please; I'm looking for C++ constructs.)
Update: Yes, I do need accessor functions, because I need to take pointers to these accessors for something called Property Descriptors, which enable huge savings in my GUI code (non-library).
.h file
private:
bool _visible;
public:
bool GetVisible() const { return _visible; }
void SetVisible (bool value);
// Repeat for Get/SetFlashing, Get/SetColor, Get/SetLineWidth, etc.
.cpp file
void Element::SetVisible (bool value)
{
_visible = value;
this->InvalidateSelf(); // Call method in base class
// ...
// A bit more code here, identical in 90% of my setters.
// ...
}
// Repeat for Get/SetFlashing, Get/SetColor, Get/SetLineWidth, etc.
I find myself writing almost identical accessors all the time. I already have several dozen accessors such as the one below.
This is a sure design smell that you are writing accessors "for the sake of it". Do you really need them all? Do you really need a low-level public "get" and "set" operation for each one? It's unlikely.
After all, if all you're doing is writing a getter and a setter for each private data member, and each one has the same logic, you may as well have just made the data members public.
Rather your class should have meaningful and semantic operations that, in the course of their duties, may or may not make use of private data members. You will find that each of these meaningful operations is quite different from the rest, and so your problem with repetitive code is vanquished.
As n.m. said:
Easy: avoid accessors. Program your classes to do something, rather than have something.
Even for those operations which have nothing more to them, like controlling visibility, you should have a bool isVisible() const, and a void show(), and a void hide(). You'll find that when you start coding like this it will promote a move away from boilerplate "for the sake of it" getters & setters.
Whilst I think Lightness Races in Orbit makes a very good point, there is also a few ways that can be used to implement "repeating code", which can be applied, assuming we do indeed have a class that have "many things that are similar that need to be controlled individually, so kind of continuing on this, say we have a couple of methods like this:
void Element::Show()
{
visible = true;
Invalidate();
// More code goes here.
}
void Element::Hide()
{
visible = false;
Invalidate();
// More code goes here.
}
Now, to my view, this breaks the DRY (Do not Repeat Yourself) principle, so we should probably do something like this:
void Element::UpdateProperty(bool &property, bool newValue)
{
property = value;
Invalidate();
// More code goes here.
}
Now, we can implement Show and Hide, Flash, Unflash, Shaded etc by doing this, avoiding repetition inside each function.
void Element::Show()
{
UpdateProperty(visible, true);
}
If the type isn't always bool, e.g. there is a position, we can do:
template<typename T>void Element::UpdateProperty(T &property, T newValue)
{
property = value;
Invalidate();
// More code goes here.
}
and the MoveTo becomes:
void Element::MoveTo(Point p)
{
UpdateProperty(position, p);
}
Edit based on previously undisclosed information added to question:
Obviously the above technique can equally be applied to any form of function that does this sort of work:
void Element::SetVisible(bool value)
{
UpdateProperty(visible, value);
}
will work just as well as for Show described above. It doesn't mean you can get away from declaring the functions, but it reduces the need for code inside the function.
I agree with Lightness. You should design your classes for the task at hand, and if you need so many getters and setters, you may be doing something wrong.
That said, most good IDEs allow you to generate simple getters and setters, and some might even allow you to customize them. You might save the repetitive code as a template and select the code fragment whenever needed.
You may also use a customizable editor like emacs and Vim (with Ultisnips) and create some custom helping functions to make your job easy. The task is ripe for automation.
The only time you should ever write a get/set set of functions in any language is if it does something other than just read or write to a simple variable; don't bother wrapping up access to data if all you're doing is make it harder for people to read. If that's what you're doing, stop doing anything.
If you ever do want a set of get/set functions, don't call them get and set -- use assignment and type casting (and do it cleverly). That way you can make your code more readable instead of less.
This is very inelegant:
class get_set {
int value;
public:
int get() { return value; }
void set(int v) { value = v; }
};
This is a bit better
class get_set_2 {
value_type value;
bool needs_updating;
public:
operator value_type const & () {
if (needs_updating) update(); // details to be found elsewhere
return value;
}
get_set_2& operator = (value_type t) {
update(t); // details to be found elsewhere
return *this;
}
};
If you're not doing the second pattern, don't do anything.
I'm a tad late again, but I wanted to answer because I don't totally agree with some other here, and think there's additional points to lay out.
It's difficult to say for sure if your access methods are code smells without seeing a larger codebase, or have more information about intent. Everyone here is right about one thing: access method are generally to be avoided unless they do some 'significant work', or they expose data for the purpose of generic-ism (particularly in libraries).
So, we can go ahead and call methods like the idiomatic data() from STL containers, 'trivial access method'.
Why not use trivial access methods?
First, as others have noted, this can lead to an over-exposure of implementation details. At it's best such exposure makes for tedious code, and at it's worse it can lead to obfuscation of ownership semantics, resource leaks, or fatal exceptions. Exposure is fundamentally opposite of object orientation, because each object ought to manage its own data, and operations.
Secondly, code tends to become long, hard to test, and hard to maintain, as you have noted.
When to use trivial access methods?
Usually when their intent is specific, and non-trivial. For example, the STL containers data() function exists to intentionally expose implementation details for the purposes of genericism for the standard library.
Procedural style-structs
Breaking away from directly object-oriented styles, as implementation sometimes does; you may want to consider a simple struct (or class if you prefer) which acts as a data carrier; that is, they have all, or mostly, public properties. I would advise using a struct only for simple holders. This is opposed to a class ought to be used to establish some invariant in the constructor. In addition to private methods, static methods are a good way to illustrate invariants in a class. For example, a validation method. The invariant establishment on public data is also very good for immutable data.
An example:
// just holds some fields
struct simple_point {
int x, y;
};
// holds from fields, but asserts invariant that coordinates
// must be in [0, 10].
class small_point {
public:
int x, y;
small_point() noexcept : x{}, y{} {}
small_point(int u, int v)
{
if (!small_point::valid(u) || !small_point::valid(u)) {
throw std::invalid_argument("small_point: Invalid coordinate.");
}
x = u;
y = v;
}
static valid(int v) noexcept { return 0 <= v && v <= 10; }
};

Is there syntax to prevent instances of a class being const?

Let's say that I create a class where the primary use case will have the user always calling methods that modify its members. Or, looking at it another way, creating a class where every method will modify a class member(s).
For example, let's work with this dummy class:
class Foo
{
public:
void setM_1(int);
void setM_2(char);
void setM_3(float);
private:
int m_1;
char m_2;
float m_3;
};
For this Foo class, creating a const instance of it doesn't make sense, since every method is guaranteed to modify a member.
My goal is this: define this class in such a way that const-ly instantiating this class would have no effect. That is to say, a const Foo instance would be able to call every method that a Foo instance can.
I was able to achieve this behavior by marking every method const, declaring all non-const members mutable, and providing a ctor that initialized all members of the class.
So the const-ignorant version of Foo looks like:
class Foo
{
public:
Foo()
{
m_1 = 0;
m_2 = '\0';
m_3 = 0.0f;
}
void setM_1(int) const;
void setM_2(char) const;
void setM_3(float) const;
private:
mutable int m_1;
mutable char m_2;
mutable float m_3;
};
My question is this: is there a more elegant way of doing this?
Or, is this just bad class design? (no debates please).
After Answer Edit:
It's official: I just took a brain crap.
Kerrek SB is right: creating a const Foo and using class-modifying methods would raise compiler errors anyways, so my "const-ignorant" Foo is pointless.
A little documentation would solve my "problem".
No wonder I had a hunch that this was terrible class design.
Excuse me everyone, this question must've been an eyesore. Thank you for the constructive criticism.
Your goal is fundamentally incorrect. const exists not for funsies, but because it means that you really need const. Such a class would break horribly as e.g. a set key- where mutating it would break the ordering. There are other pitfalls like what happens when you provide it as a temporary in certain cases.
If your class cannot be realistically used in a const way, the interface should not lie about it and pretend that it's const when it isn't.
As for your question about bad design, I can safely say that yes, this sounds like a truly terrible design.
No, thank frak.
This makes no sense and would be extremely confusing/dangerous.
If you don't think it makes sense to have a const T then don't instantiate a const T.
From a language point of view, what bad things will happen if a class cannot be const:
First of all, is it that declaring an L-value of type const for it is not allowed, or that const references to it are also prohibited?
If you do not have const reference, then you won't have the default copy constructor, or copy assignment operator. You can't have the class be a member of any other class either, unless that also cannot be const.
I have seen some (sloppy) code where people implement iterators, and because they get tired of writing boilerplate, they implement const_iterators by const_casting away the const and using the non-const iterator implementation. They do this with classes that they know won't "actually" be const, so it won't be undefined behavior in their program. Potentially, not much fun for maintainers though.
For these classes, the class "cannot be const" in the sense that if you actually created a const one on the stack and used it normally you could technically get UB.
If what you want is for the compiler to complain when someone creates a const instance of some class, I think that doesn't really make sense. Const is fundamentally a "promise not to change something". Why would you want to forbid the programmer from making a promise about how he will use something, that seems only beneficial.

How to keep this const-correct without cheating the compiler?

I have a C++ class like that:
class Example {
public:
int getSomeProperty(int id) const;
private:
lazilyLoadSomeData();
}
Basically getSomeProperty() return some data that has been loaded using lazilyLoadSomeData(). Since I don't want to load this data until needed, I'm calling this method within getSomeProperty()
int Example::getSomeProperty(int id) const {
lazilyLoadSomeData(); // Now the data is loaded
return loadedData[id];
}
This does not work since lazilyLoadSomeData() is not const. Even though it only changes mutable data members, the compiler won't allow it. The only two solutions I can think of are:
Load the data in the class constructor, however I do not want to do that, as lazily loading everything makes the application faster.
Make lazilyLoadSomeData() const. It would work since it only changes mutable members, but it just doesn't seem right since, from the name, the method is clearly loading something and is clearly making some changes.
Any suggestion on what would be the proper way to handle this, without having to cheat the compiler (or giving up on const-correctness altogether)?
You could make a proxy member object which you declare mutable and which encapsulates the lazy-loading policy. That proxy could itself be used from your const function. As a bonus you'll probably end up with some reusable code.
I would forward the call to a proxy object which is a mutable member of this class, something like this:
class Example {
public:
int getSomeProperty(int id) const
{
m_proxy.LazyLoad();
return m_proxy.getProperty(id);
}
private:
struct LazilyLoadableData
{
int GetProperty(int id) const;
void LazyLoad();
};
mutable LazilyLoadableData m_proxy;
};
Make lazilyLoadSomeData() const. It would work since it only changes mutable members, but it just doesn't seem right since, from the name, the method is clearly loading something and is clearly making some changes.
No, it's not making some changes, at least not from the viewpoint whoever called getSomeProperty. All changes, if you're doing it right, are purely internal, and not visible in any way from the outside. This is the solution I'd choose.

Is it OK to return a const reference to a private member?

I need to implement read-only access to a private member container. If I return a constant reference is it possible to const_cast it and obtain a full access to the member? What's the technique to be used?
Thanks.
Is it safe to return a const reference to a private member
Yes as long as the lifetime of the reference does not exceed the lifetime of the object which returned it. If you must expose the private member you do not want modified, this is a good way to do so. It's not foolproof but it's one of the better ways to do so in C++
Is it possible to use const_cast to actually mess around with member
Yes and there is nothing you can do to prevent this. There is no way to prevent someone from casting away const in C++ at any time. It's a limitation / feature of C++.
In general though, you should flag every use of const_cast as a bug unless it contains a sufficiently detailed comment as to why it's necessary.
Returning a const & is a sensible thing to do in many circumstances, particularly if the object being returned is large or cannot be copied.
Regarding the const_cast, remember the "private" access specifier in C++ is there as an aid to the programmer - it is not intended to be a security measure. If someone wants access to an object's private members, it can get them, no matter what you try to do to prevent it.
const int &ref = your_object.your_function();
*(int*)&ref = 1234;
Don't worry about users doing const_casts just to break your invariants. If they really want to break your code they can without you providing accessors to your internal attributes. By returning a constant reference, the common user will not mistakenly modify your data.
Encapsulation prevents mistakes, not espionage A malicious coder can break it anyway if they really care and know the environment (compiler). Const-ness is lost in the compilation process (in all compilers I know of). Once the compilation unit is converted into binary objects, those objects do not know about const-ness, and that can be exploited to take advantage.
// a.h
class A
{
public:
A( int a ) : data_( a ) {}
int get() const { return data_; }
private:
int data_;
};
// malicious.h
class A;
void change( A& a, int new_value );
// malicious.cpp
// does not include a.h, but redefines an almost exact copy of it
class A {
public:
A( int a ) : data_( a ) {}
int get() const { return data_; }
int data_; // private removed
};
void change( A& a, int new_value )
{
a.data_ = new_value;
}
// main.cpp
#include "a.h"
#include "malicious.h"
int main()
{
A a(0);
change( a, 10 );
std::cout << a.get() << std::endl; // 10
}
While the code above is incorrect (One definition rule is broken, there are two definitions for class A), the fact is that with most compilers the definition of A and malitious A are binary compatible. The code will compile and link, and the result is that external code has access to your private attributes.
Now that you know of it, don't do it. It will later be a maintenance pain in the ***. That has cost Microsoft quite a bit of money in providing backwards compatibility to software that used private parts of the API returned objects (new versions of the API that shared the same public interface but changed the internals would break some third party application code). With some broadly available software the provider (Microsoft in this case) will go through the pain of providing backwards compatibility, but with lesser known applications they won't and suddenly your previously running application will fail in all sort of ways.
I think it was Herb Sutter that once said that one should "Protect against Murphy, not against Machiavelli." That is, you should do everything possible to protect against the code being used incorrectly by accident, but there's nothing you can do about people abusing your code on purpose.
If someone really wants to break your code, they can, even if it's by #define private public before including your header (and thus creating an ODR violation, but I digress).
So yes, passing back a const ref is fine.
const_cast can be definitely used to obtain the full access to the member. I guess you can not stop people if they are hell bent on shooting themself on the foot. If the private member is not heavy, consider returning a copy of that variable.
Yes, so it's probably not what you want to do. On the other hand, if someone is going to the trouble of const casting your reference, it's possible they really know what they are doing.
It is possible to obtain a full access. But what for?
Don't forget to make accessor to be const correct
const MyType& getMyValue() const;
Also you can inject you private value in the callback.
void doJob( callback c )
{
c( myPrivateValue_ );
}
According to Scott Meyer's book, Effective C++ (see item #28), you should avoid it. Here is an excerpt from item #28:
This is why any function that returns a handle to an internal part of
the object is dangerous. It doesn’t matter whether the handle is a
pointer, a reference, or an iterator. It doesn’t matter whether it’s
qualified with const. It doesn’t matter whether the member function
returning the handle is itself const. All that matters is that a
handle is being returned, because once that’s being done, you run the
risk that the handle will outlive the object it refers to.

What does the const operator mean when used with a method in C++?

Given a declaration like this:
class A {
public:
void Foo() const;
};
What does it mean?
Google turns up this:
Member functions should be declared with the const keyword after them if they can operate on a const (this) object. If the function is not declared const, in can not be applied to a const object, and the compiler will give an error message.
But I find that somewhat confusing; can anyone out there put it in better terms?
Thanks.
Consider a variation of your class A.
class A {
public:
void Foo() const;
void Moo();
private:
int m_nState; // Could add mutable keyword if desired
int GetState() const { return m_nState; }
void SetState(int val) { m_nState = val; }
};
const A *A1 = new A();
A *A2 = new A();
A1->Foo(); // OK
A2->Foo(); // OK
A1->Moo(); // Error - Not allowed to call non-const function on const object instance
A2->Moo(); // OK
The const keyword on a function declaration indicates to the compiler that the function is contractually obligated not to modify the state of A. Thus you are unable to call non-const functions within A::Foo nor change the value of member variables.
To illustrate, Foo() may not invoke A::SetState as it is declared non-const, A::GetState however is ok because it is explicitly declared const. The member m_nState may not be changed either unless declared with the keyword mutable.
One example of this usage of const is for 'getter' functions to obtain the value of member variables.
#1800 Information: I forgot about mutable!
The mutable keyword instructs the compiler to accept modifications to the member variable which would otherwise cause a compiler error. It is used when the function needs to modify state but the object is considered logically consistent (constant) regardless of the modification.
This is not an answer, just a side comment. It is highly recommended to declare variables and constants const as much as possible.
This communicates your intent to users of your class (even/especially yourself).
The compiler will keep you honest to those intentions. -- i.e., it's like compiler checked documentation.
By definition, this prevents state changes you weren't expecting and can, possibly, allow you to make reasonable assumptions while in your methods.
const has a funny way of propagating through your code. Thus, it's a really good idea to start using const as early and as often as possible. Deciding to start const-ifying your code late in the game can be painful (easy, but annoying).
If you're using a language with static, compile time checks it's a great idea to make as much use of them as possible... it's just another kind of testing really.
Functions with const qualifier are not allowed to modify any member variables. For example:
class A
{
int x;
mutable int y;
void f() const
{
x = 1; // error
y = 1; // ok because y is mutable
}
};
C++ objects can be declared to be const:
const A obj = new A();
When an object is const, the only member functions that can be called on that object are functions declared to be const. Making an object const can be interpreted as making the object readonly. A const object cannot be changed, i.e. no data members of the object can be changed. Declaring a member function const means that the function is not allowed to make any changes to the data members of the object.
Two suggested best practices from experience:
(1) Declare const functions whenever possible. At first, I found this to be just extra work, but then I started passing my objects to functions with signatures like f(const Object& o), and suddenly the compiler barfed on a line in f such as o.GetAValue(), because I hadn't marked GetAValue as a const function. This can surprise you especially when you subclass something and don't mark your version of the virtual methods as const - in that case the compile could fail on some function you've never heard of before that was written for the base class.
(2) Avoid mutable variables when it's practical. A tempting trap can be to allow read operations to alter state, such as if you're building a "smart" object that does lazy or asynchronous i/o operations. If you can manage this with only one small mutable variable (like a bool), then, in my experience, this makes sense. However, if you find yourself marking every member variable as mutable in order to keep some operations const, you're defeating the purpose of the const keyword. What can go wrong is that a function which thinks it's not altering your class (since it only calls const methods) my invoke a bug in your code, and it could take a lot of effort to even realize this bug is in your class, since the other coder (rightly) assumes your data is const because he or she is only calling const methods.
const has a funny way of propagating through your code. Thus, it's a really good idea to start using const as early and as often as possible. Deciding to start const-ifying your code late in the game can be painful (easy, but annoying).
Additionally, you will easily run into problems if methods that should be const aren't! This will creep through the code as well, and make it worse and worse.
that will cause the method to not be able to alter any member variables of the object