Do const member functions call only const member functions?
class Transmitter{
const static string msg;
mutable int size;
public:
void xmit() const{
size = compute();
cout<<msg;
}
private:
int compute() const{return 5;}
};
string const Transmitter::msg = "beep";
int main(){
Transmitter t;
t.xmit();
return EXIT_SUCCESS;
}
If i dont make compute() a const, then the compiler complains.
Is it because since a const member function is not allowed to modify members, it wont allow
any calls to non-consts since it would mean that the const member function would be 'indirectly' modifying the data members?
Is it because since a const member function is not allowed to modify members, it wont allow any calls to non-consts since it would mean that the const member function would be 'indirectly' modifying the data members?
Yes.
Yes: const member functions only see the const version of the class, which means the compiler will not find any non-const members (data or functions) inside a const member function.
This effect propagates to const objects (instances) of the class, where only const members are accessible.
When applied correctly, const will allow for the programmer to check his use of the class and make sure no unwanted changes are made to any objects that shouldn't be changed.
Yes. When you call 'xmit()', its 'this' pointer will be const, meaning you can't then call a non-const method from there, hence 'compute()' must be const
As others have said; yes.
If there is a particular reason you want compute to be non const, for example if it uses some local cache to store calculations, then you can still call it from other functions that are declared const by declaring a const version
private:
int compute() const{return ( const_cast<Transmitter*>(this)->compute());}
int compute() {return 5;}
Your assertion and your analysis are both correct.
Related
The assignment is to create a constant function getArea() that returns the area of a rectangle.
double getArea() {
return width * height;
}
Is this it?
Do I put const after the parameters?
I don't really understand what I'm being asked.
In C++, a function becomes const when const keyword is used in function’s declaration. The idea of const functions is not allow them to modify the object on which they are called.
double getArea() const {
return width * height;
}
const after the (empty) argument list in the function declarations. indicates that getArea() function do not modify the state of a object i.e. data member of a object.
Please refer this link for more explanation: http://www.codeproject.com/Articles/389602/Constant-Member-Functions-Are-Not-Always-Constant
double getArea() const
{
return width * height;
}
const keyword is used when the user doesnt want to modify or change the values of that variable or function.
Just like the built-in data types (int, double, char, etc…), class objects can be made const by using the const keyword. All const variables must be initialized at time of creation.
Once a const class object has been initialized via constructor, any attempt to modify the member variables of the object is disallowed, as it would violate the constness of the object. This includes both changing member variables directly (if they are public), or calling member functions that sets the value of member variables.
const class objects can only call const member functions. A const member function is a member function that guarantees it will not change any class variables or call any non-const member functions.
SOURCE : leancpp.com
Consider:
class ClassType
{
int x;
public:
ClassType(int _x) : x(_x) {}
int GetX() { return x;}
};
const ClassType object(20);
object.GetX();
This will fail to compile, since the object is const (readonly). But GetX is not marked const (readonly). length(), size(), IsOpen() are example of methods that may be called from a read only object. Hence the class should facilitate such (const) functions for const object.
You generally don't create const object, but you do pass them like:
void foo(const ClassType& obj);
Therefore, the GetX function should be:
int GetX() const { return x;}
const make a promise or a contract that this function doesn't modify this object.
The title already says all. Let me expand a little nevertheless: I've class whose all attributes are const:
template< class perm = Perm16 >
class PermutationGroup {
public:
using StrongGeneratingSet = std::vector< std::vector< perm > >;
const std::string name;
const uint64_t N;
const StrongGeneratingSet sgs;
PermutationGroup(std::string name, uint64_t N, StrongGeneratingSet sgs) :
name(name), N(N), sgs(sgs) { assert(check_sgs()); };
bool check_sgs() const; // defined as const
bool is_canonical(vect v) const; // defined as const
[...]
};
Is it of any use to define all member function as const as well ? Or am I needlessly repeating myself ?
If you do not declare the member functions as const, you can't invoke them on const objects or objects referenced by a const reference. For example, the following won't work:
const PermutationGroup& group = PermutationGroup("foobar", 42, ...);
group.check_sgs(); // ERROR: can't invoke non-const function on const objects
Declaring your methods as const means that you can call them on a const-qualified object. It's not necessary to declare them const just because there are no mutable fields in the class, but in general, it's easier to write const-correct code if you always declare methods that don't modify anything as const.
Does a class with all attributes const need to have member function declared const as well?
Declaring a member variable const is different than declaring a member function const. When a member variable is declared const it cannot be modified. It can still be accessed by member functions even those not declared const, they just can't be modified.
Decalring a member function const is saying this function does not modify this object. The function is not allowed to change any member variable unless it's declared mutable. It also cannot call member functions that are not declared const as those functions would be allowed to modify the object.
Declaring member functions as const is important as it allows those functions to be called on constant instances of the class they belong to. Nosid provides a great example in their answer.
No it does not.
That been said, constness on behalf of the attributes implies constness on behalf of the instance, so even if a member function is non const it won't be able to behave as such (ie cause state mutation)
The other way around is not true though. For example
int myClass::example() const {
member = 1;
}
is the same as
int myClass::example() const {
this->member = 1;
}
and constness of the member function means constness of this pointer. This is slightly different from promising that the "raw bits" of the object's struct aren't going to change. For example, reference members can be modified by const member functions
To sum up : Declaring a member function as const becomes mandatory when it's to be used with a this pointer that is const. In your case, not declaring one as const would just be futile (and break the inspector / mutator semantics .. that being less of a deal).
say i have the following C++ class.
class C
{
int foo() const;
int & foo();
};
and i just call myC.foo(), i can see using the debugger that it calls the one with the reference.
why?
thanks!
It's likely because myC is a non-const value and hence the compiler is prefering the non-const method. The const method will only be preferred when accessed from a const value. For example
C value1;
value1.foo(); // int& foo();
const C value2;
value2.foo(); // int foo() const;
EDIT
Also, as Oli pointed out, overload resolution in C++ is not affected by the return type of the method. So it won't pick one of these signatures over the other based on the way in which the value is used.
Because myC must have not been an const obj.
C++ allows functions to be overloaded on the basis of the const keyword.
If a const object of the class is created only const member functions can be called through that object because they guarantee that they wont modify the state of the object.
a non const object can call both const as well as non const member functions but compilers gives preference to non const member functions over const member functions and hence the behavior in your case.
I was going through: C++ FAQs about inheritance and decided to implement it (just to learn it)
#include "Shape.h"
void Shape::print() const
{
float a = this->area(); // area() is pure virtual
...
}
now, everything (well, almost) works as described in item: faq:23.1 except that print() is const and so it can't access the "this" pointer, as soon as you take out const, it works.
Now, C++ FAQs have been around for a while and are usually pretty good. Is this a mistake?
Do they have typo or am I wrong? If I'm wrong, I would like to know how is it possible to access the "this" pointer in a const function.
The problem is that the area() function is not const. If that function was const, then this would compile fine. Since your inside a const function, the this pointer is const and therefore you can only call const functions on it.
Why couldn't this be accessed? The point is, only const members and methods can be used. So if Shape::area() is declared const, there is no problem. Also, you can freely read data member values, but not assign to them:
class Shape
{
int i;
void print() const;
virtual float area() const = 0;
virtual void modify() = 0;
};
void Shape::print() const
{
float a = this->area(); // call to const member - fine
int j = this->i; // reading const member - fine
this->modify(); // call to non const member - error
this->i++; // assigning to member - error
}
If print is defined as const, then it can use this to access const members but not to access non-const members: so it can invoke this->area() if-and-only-if the area method is declared as const (i.e. if the area method promises that if it's invoked then it won't mutate its Shape instance).
It is also a good practice to declare all functions as const by default, and only not do so when you actually need to modify the object. This will also help finding errors of the kind where some function modifies something it is not meant to.
You certainly can access the this pointer, but in a const function it becomes a pointer to a const object. Remember, the this pointer isn't a real pointer instance, so it can change its type at different points in the program.
Too much C# and too little C++ makes my mind dizzy... Could anyone remind me what this c++ declaration means? Specifically, the ending "const". Many thanks.
protected:
virtual ostream & print(ostream & os) const
A const method will simply receive a const this pointer.
In this case the this pointer will be of the const ThisClass* const type instead of the usual ThisClass* const type.
This means that member variables cannot be modified from inside a const method. Not even non-const methods can be called from such a method. However a member variable may be declared as mutable, in which case this restriction will not apply to it.
Therefore when you have a const object, the only methods that the compiler will let you call are those marked safe by the const keyword.
The ending const means that the print function shouldn't be able to change the state of any of the members of the class it is declared in (and therefore cannot call any member functions of that class which are not also declared const).
In the example below, the print function in the class Foo cannot change any of the member variables of Foo (unless they are declared mutable), and cannot call any non-const functions in Foo.
class Foo {
public:
Foo(string value) { m_value = value; }
protected:
ostream & print(ostream & os) const {
m_value = string("foobar"); // won't compile
os << m_value;
return os;
}
private:
string m_value;
};
The const on the method declaration tells the compiler that the function is safe to call on a const object of the type the function is a member of. It also signals to the compiler that the function is not supposed to alter the state of the object and it will not be able to change any member variables that are not marked as mutable.
If you omit the const, this code will not work:
const Foo bar;
bar.print(std::cout); // Will fail to compile unless 'print' is marked const
You're declaring a protected virtual method named print which takes as a parameter a reference to an ostream and returns a reference to an ostream.
The const keyword means the method won't be able to alter the state of the object, the this pointer will be const.
A virtual method is a method whose behavior can be overridden within an inheriting class, basically the virtual keyword gives C++ its' ability to support polymorphism.
And finally if you don't know what is a reference go there
Comming from C# I suppose you know what protected means :)