C++: "const" in front of a class method - c++

Taking for example this method declaration:
const Vector Vector::operator - ( const Vector& other ) const;
I know that the second const makes the Vector passed as an argument immutable, and that the last const declares that the method does not change the current instance of the Vector class....
But what exactly does the first const mean or lead to?

It is an outdated security measure to prevent nonsense code like a - b = c to compile.
(I say "outdated" because it prevents move semantics which only works with non-const rvalues.)

The first const means that this operator will return a constant Vector object.

It means the return value is a const Vector.
It has more meaning in cases such as this: const int& Vector::get(int index) const;

Related

Can const functions call non-const functions on local objects?

I have a question regarding const functions: can a const function call non-const functions on local objects in the function? Here's an example of what I'm talking about:
template <class T>
Set<T> Set<T>::setUnion (const Set<T> & other) const
{
Set<T> unionSet; //create union set
unionSet.merge(internalStorage); //merge it with our current set
unionSet.merge(other.internalStorage); //merge it with other set, duplicates will not be added
return unionSet;
}
This function takes two sets and returns the union of the sets. The problem though is that the merge function is not const and the merge function also calls the add function which is also not const, so I cannot see any other way to create a union set with solely these two functions given that the setUnion function has to be const.
PS: I know the solution without doing a const function, the reason I'm doing it this way is because my professor defined it as such. Thanks.
Yes. The only restriction on a const member function is that it can't modify the object its called on; it can modify any other (non-const) object.
A const member function means that the this it receives has type roughly equivalent to T const *const this1.
That means you can't invoke any non-const functions via this, but it does not affect anything you do that doesn't go through this (explicitly or implicitly).
1. Technically, you can't really write out the type of this truly correctly, but the type I've given here is close enough for the current discussion.

why do ref parameters in functions for stable_sort need const

If I remove the const from the function parameters clang throws an error. This error in combination with missing const only appear with ref variables. What's going on?
vector<string> v = {"the", "quick", "brown", "fox"};
bool compareWords(const string & s1, const string & s2)
{
return s1.size() < s2.size();
}
stable_sort(v.begin(), v.end(), compareWords);
Strictly speaking,
bool compareWords(string & s1, string & s2)
{
return s1.size() < s2.size();
}
should work. The only requirement for compareWords is that it should not modify the arguments.
Here's some info from http://en.cppreference.com/w/cpp/algorithm/stable_sort
The signature of the comparison function should be equivalent to the following:
bool cmp(const Type1 &a, const Type2 &b);
The signature does not need to have const &, but the function object must not modify the objects passed to it.
However, some compilers take that requirement to mean that the arguments should be either const & or simply objects.
It's to help you ensure that you don't modify the arguments to the comparator.
If you were to modify the elements being sorted during the sort operation then the comparator might return inconsistent results, which would break the sorting algorithm - with potentially unlimited ill effects ("undefined behavior").
By saying string & s1 as a parameter without the const implies that you will be changing the underlying value back in the calling function. However, that value is the return value of a function -- it's not stored anywhere, it can't be changed.
(OK, due to some compiler magic it is stored somewhere, but that location is not accessible to the calling function, so you are still implying you want to do something that you can't do)
According to the C++ Standard
It is assumed that comp will not apply any non-constant function
through the dereferenced iterator.
So to provide this restriction objects of dereferenced iterators are considered as const references.

Overloading the [] operator of a template class, get and set, in c++

Basically, I'm trying to make template map/dictionary class for c++ (I know this have already been done, assume I'm masochistic).
I started up, writing this skeleton:
#pragma once
template <class T>
class AssArray
{
int _size;
int _position;
public:
AssArray(int size);
~AssArray(void);
const T& operator [](char* b) const;
T& operator [](char* b) const;
//I read this should be done sth like this when researching, though an explanation would be nice.
};
Now, I need to be able to get (T=AssArray["llama"]), set (AssArray["llama"]= T) and override (AssArray["llama"]= newT).
Doing this is pretty straight forward, just loop it through etc, the real problem here is the operators;
if I use AssArray["llama"]= T, how am I supposed to get the value of T into the operator overloading-function?
I've only found explanations describing the solutions briefly, and can not really follow.
Please enlighten me.
All you have to do is correct your signatures like so:
const T& operator [](char* b) const;
T& operator [](char* b);
I've removed the const qualifier from the second operator.
if I use AssArray["llama"]=T, how am I supposed to get the value of T into the operator overloading-function?
You don't. You just return a reference to where the new value should be stored, and the compiler will take care of the rest. If "llama" does not exist in the array, you need to create an entry for it, and return a reference to that entry.
Since the operator[] returns a reference to T if you want to say assArray["str"] = T the type T has to know what to do with the operator=. If T does not have the operator= overloaded you have to overload the operator= in type T.
operator[] has nothing to do with assignments. It should just return the element at the given index.

Class storing pointers to vector in C++

I'm implementing a class Aviary, which can store pointers to Bird-objects. Now, I have the following:
class Aviary {
public:
const Bird &operator[](const size_t index) const {
return birds[index];
}
Bird &operator[](const size_t index) {
return birds[index];
}
private:
std::vector<Bird*> birds;
The Bird-objects are stored as pointers in order to avoid object-slicing. However, there is a problem with the operator[]-implementation (Reference to type 'const Bird' could not bind to an lvalue of 'const value_type' (aka 'Bird *const')).
How do I implement the operator[] properly?
Since you store pointers, you should dereference the pointer for return reference.
const Bird &operator[](const size_t index) const {
return *birds[index];
}
Bird &operator[](const size_t index) {
return *birds[index];
}
Side note: use smart pointers, instead of raw pointers.
Two side notes:
The const in a parameter passed by value (const size_t index) is useless and your compiler will ignore it. You can try declaring it with const and removing the const in the implementation: the compiler will correctly consider that your implementation matches the declaration.
The canonical way to implement the non-const version of operator[] is as follows:
As follows
Bird &operator[](size_t index) {
return const_cast<Bird&>(const_cast<const Aviary*>(this)->operator[](index));
}
I know all those const_cast look ugly, but they are both safe and this is the right way to ensure that both versions of operator[] do the same (you just need to maintain the const version from now on), while also making sure that your are not doing any non-const operation in the const version.
Apart from that, the problem with your code is that you are returning pointers, not (references to) the values pointed by them, as Luchian and ForEveR have already pointed out.
You need to dereference:
return *(birds[index]);
birds[index] is a Bird*, so you can't directly return it as a Bird&.

why sometime a function return a const, or const reference

First, why return const?
say I have
friend const MyVec operator-(const MyVec& left, const MyVec& right)
so is returning const makes me cannot do:
mva - mvb = mvc;
Second, why return const reference?
if there is:
friend const MyVec& operator++(MyVec& v)
with const I cannot: (++mva) = mvc
if it is
MyVec& operator++(MyVec& v)
I can:++(++mva) // with increment twice.
am I understanding right?
There is not any good reason to return a const object. However, there are many good reasons to return pointers or references to const objects.
The program might have an object that is very expensive to copy, so it returns a reference. However, the object should not be changed through that reference. For example, it might be part of a sorted data structure and if its values were modified it would no longer be sorted correctly. So the const keeps it from being modified accidentally.
Arithmetic operator functions should not return const objects, because of exactly the problems in your question.
Dereferencing an iterator should return a const reference. That is if it is operating on a collection of const objects or possibly on a const collection. This is why class functions sometimes have two copies of a function with the second copy using a const on the function itself, like this:
T& operator[](size_t index);
const T& operator[](size_t index) const;
The first function would be used on non-const objects and the second function would be used for const objects.
Yes your understanding is correct. To avoid accidental assignments, one can return an object by const or const reference.
With operator -, you return an object by value. To avoid it getting edited accidently, one can return by const value, because anyways the object will be mostly a temporary.
For operator ++, conventionally it returns reference, however to avoid situations as (++ x) = y; you can return it by const reference.