Not sure what a constant function is in c++ - c++

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.

Related

const in function prototype

If we have a function prototype like this :
const CString function(...)
{
CString x;
//do some stuff
return x;
}
does this mean that function returns a const CString ? because const in C++ can be placed in front of a method inside a class to tell the compiler that the attributes will not be modified (or not mutable)
I ask this "dumb" question, because in another case we can have something like this :
static CString function(...)
{ }
And in this case static relates to "function" and not to the variable returned.
In C++ const return_type function_name(params) means you have a function that returns a const return_type. If you have static return_type function_name(params) then this marks the function as static and you no longer need an instance of the class to call this function. If you want to mark a function as const meaning that it will not moodify the class contents then you need to place the const after the function as
return_type function_name(params) const
^^^^^
does this mean that function returns a const CString ?
Yes it does.
because const in C++ can be placed in front of a method inside a class to tell the compiler that the attributes will not be modified (or not mutable)
No it can't, the const has to be placed after the method to achieve that.
class MyClass {
// ...
const CString function();
// ...
}
A function returning const CString.
class MyClass {
// ...
CString const function();
// ...
}
Same thing.
class MyClass {
// ...
CString function() const;
// ...
}
A function that can be called on a constant object, as it "promises" not to change internal state.
As a rule of thumb, const is always after the thing declared constant...
...except for the old C-style const <type>, kept for backward compatibility.
The following two lines are the same thing, a constant pointer to a constant int. Note that to make the pointer constant, the const has to be trailing the *:
const int * const p1; // the exception
int const * const p2;
To return a const value from a function use :
const CString function(...)
{
CString x;
//do some stuff
return x;
}
To tell the compilater that attributes won't change use :
CString myClass::function(...) const
{
CString x;
//do some stuff
return x;
}
const CString function(...) returns a const CString,
but it is deprecated as rarely useful and by the fact that disallows move on the temporary. So, in CString s; s = foo();, a copy is done instead of a move.
The most significant usage was to forbid things like
foo() = CString(..);
C++11 introduces ref qualifier on method and r-value reference which allows to fix that differently:
Obj& operator = (const Obj& rhs) & ; // Note the final &
A function declared as const CString function(...) returns a const CString. This the the same in C++ as it is in C.
If you have a C++ method defined like this:
void MyClass::function(void) cont;
That means that the method function does not modify the object.
const appearing before the method describes the attributes of the return type of the method.
So,
const CString method_name();
means that the method returns a const CString object i.e. an object that cannot be modified by the caller of this method.
const appearing after the method describes the attributes of the method itself. It tells that the method does not "mutate" or "modify" the object it operates on.
So,
const CString method_name() const;
means that the method cannot modify any of the member variables of the object used to invoke the method. It has no relation with the return type of the method.
Let us see this with an example.
class Foo
{
int x;
int GetX() const {return x;}
void SetX(int i_x) {x = i_x;}
};
In the above class definition, GetX() is a const method i.e. it is not expected to modify the object which is used to invoke them. What does this mean? When you declare a class, there is a single version of each of the member functions which gets loaded onto memory. Further, all the non-static member methods need an object to invoke them. How is this achieved? When you declare a non-static member method of the class, the C++ compiler slyly changes the signature of the methods to expect a "this" pointer, that is the pointer to the object used to invoke the method.
For a non-const method, the type of the "this" pointer expected is Class*. So our SetX() method above looks like:
void SetX(Foo* this, int i_x) {this->x = i_x;}
You can use the this pointer to modify the object(x is part of the object right!)
However, for a const method, the type of the "this" pointer passed is
const Class* i.e. you cannot modify the object using the "this" pointer. So GetX becomes
int GetX(const Foo* this) {return this->x; }
Since the type of the this pointer is const Foo*, you cannot change the object the pointer points to i.e. you cannot do someething like:
x = 100;
which would translate to this->x = 100; which the compiler will complain about.

Does a class with all attributes const need to have member function declared const as well?

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).

const before parameter vs const after function name c++

What is the difference betweeen something like this
friend Circle copy(const Circle &);
and something like this
friend Circle copy(Circle&) const;
I know const after the function is used to tell the compiler that this function won't attempt to change the object it is called on, what about the other one?
The first form means that the (state of the) Circle object bound to the reference which is the parameter of the copy() function will not be altered by copy() through that reference. The reference is a reference to const, so it won't be possible to invoke member functions of Circle through that reference which are not themselves qualified as const.
The second form, on the other hand, is illegal: only member functions can be const-qualified (while what you are declaring there is a global, friend function).
When const qualifies a member function, the qualification refers to the implicit this argument. In other words, that function will not be allowed to alter the state of the object it is invoked on (the object pointed to by the implicit this pointer) - with the exception of mutable objects, but that's another story.
To say it with code:
struct X
{
void foo() const // <== The implicit "this" pointer is const-qualified!
{
_x = 42; // ERROR! The "this" pointer is implicitly const
_y = 42; // OK (_y is mutable)
}
void bar(X& obj) const // <== The implicit "this" pointer is const-qualified!
{
obj._x = 42; // OK! obj is a reference to non-const
_x = 42; // ERROR! The "this" pointer is implicitly const
}
void bar(X const& obj) // <== The implicit "this" pointer is NOT const-qualified!
{
obj._x = 42; // ERROR! obj is a reference to const
obj._y = 42; // OK! obj is a reference to const, but _y is mutable
_x = 42; // OK! The "this" pointer is implicitly non-const
}
int _x;
mutable int _y;
};
C++ class methods have an implicit this parameter which comes before all the explicit ones. So a function declared within a class like this:
class C {
void f(int x);
You can imagine really looks like this:
void f(C* this, int x);
Now, if you declare it this way:
void f(int x) const;
It's as if you wrote this:
void f(const C* this, int x);
That is, the trailing const makes the this parameter const, meaning that you can invoke the method on const objects of the class type, and that the method cannot modify the object on which it was invoked (at least, not via the normal channels).
LET'S CLEAR ALL CONFUSION RELATED TO const
const came from constant mean something is not changeable but readable.
if we qualify our variable with const keyword ,we can't change it later.
e.g.
constint var =25; const variable must be initialized when it's declared.
var =50; // gives error
if we qualify our pointer variable with const after * then we can't change pointer itself but content of pointer is changeable.
e.g.
int *const ptr = new int;
ptr = new int; //gives error
// but
*ptr=5445; //allowed
if we qualify our pointer variable with const before * then we can change pointer itself but content of pointer is not changeable.
e.g.
intconst* ptr = new int(85);
//or
constint * ptr = new int(85);
ptr = new int; // allowed
// but
*ptr=5445; // gives error
pointer and content both constant
e.g.
intconst*constptr = new int(85);
//or
constint *constptr = new int(85);
ptr = new int; // not allowed
*ptr=5445; // not allowed
Circle copy(const Circle &);
here const Circle means value of Circle is only readable ,if we try to change value of Circle inside function then it gives error.
friend Circle copy(Circle&) const;
This type of function is not for non member variable .it is used for class or structure.
Here whole function is qualified with const keyword means we can't change object member variable .
e.g
class A{ public :
int var;
void fun1()
{ var = 50; // allowed
}
void fun2()const
{ var=50; //not allowed
}
};
Circle copy(Circle&) const;
makes the function const itself. This can only be used for member functions of a class/struct.
Making a member function const means that
it cannot call any non-const member functions
it cannot change any member variables.
it can be called by a const object(const objects can only call const functions). Non-const objects can also call a const function.
It must be member function of the class 'Circle'.
Now consider the next one:
Circle copy(const Circle &);
while this one means that the parameter passed cannot be changed within the function. It may or may not be a member function of the class.
NOTE: It is possible to overload a function in such a way to have a const and non-const version of the same function.
One refers to the parameter the other to the function.
Circle copy(const Circle &);
This means that the parameter passed in cannot be changed within the function
Circle copy(Circle&) const;
The const qualified function is used for member functions and means you cannot change the data members of the object itself. The example you posted was nonsensical.
Read right-to-left
If we rewrite the first function as Circle copy(Circle const&);, which means the same thing, it becomes clear that reading right to left becomes useful. copy is a function that takes a const reference to a Circle object and returns a Circle object by reference.
friend Circle copy(const Circle &);//refers to constant parameter of the function. cant' change the value stored by parameter.
Need to remove friend in your example
Circle copy(Circle&) const;
//can't change this poniter value named as Constant member function
friend Circle copy(const Circle &);
The value of parameter will not be changed during the function calls.
friend Circle copy(const Circle &)const ;
The function is an accessor that does not change any value of class members. Generally, there are to types of functions: accessors and mutators.
Accessor: examines but does not change the state of its object.

const member functions can call const member functions only?

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.

Why can I call a non-const member function pointer from a const method?

A co-worker asked about some code like this that originally had templates in it.
I have removed the templates, but the core question remains: why does this compile OK?
#include <iostream>
class X
{
public:
void foo() { std::cout << "Here\n"; }
};
typedef void (X::*XFUNC)() ;
class CX
{
public:
explicit CX(X& t, XFUNC xF) : object(t), F(xF) {}
void execute() const { (object.*F)(); }
private:
X& object;
XFUNC F;
};
int main(int argc, char* argv[])
{
X x;
const CX cx(x,&X::foo);
cx.execute();
return 0;
}
Given that CX is a const object, and its member function execute is const, therefore inside CX::execute the this pointer is const.
But I am able to call a non-const member function through a member function pointer.
Are member function pointers a documented hole in the const-ness of the world?
What (presumably obvious to others) issue have we missed?
The constness of execute() only affects the this pointer of the class. It makes the type of this a const T* instead of just T*. This is not a 'deep' const though - it only means the members themselves cannot be changed, but anything they point to or reference still can. Your object member already cannot be changed, because references cannot be re-seated to point to anything else. Similarly, you're not changing the F member, just dereferencing it as a member function pointer. So this is all allowed, and OK.
The fact that you make your instance of CX const doesn't change anything: again, that refers to the immediate members not being allowed to be modified, but again anything they point to still can. You can still call const member functions on const objects so no change there.
To illustrate:
class MyClass
{
public:
/* ... */
int* p;
void f() const
{
// member p becomes: int* const p
*p = 5; // not changing p itself, only the thing it points to - allowed
p = NULL; // changing content of p in const function - not allowed
}
};
In this context object is a reference to a X, not a reference to a const X. The const qualifier would be applied to the member (i.e. the reference, but references can't be const), not to the referenced object.
If you change your class definition to not using a reference:
// ...
private:
X object;
// ...
you get the error you are expecting.
The instance object of class X is not const. It is merely referenced by an object which is const. Const-ness recursively applies to subobjects, not to referenced objects.
By the alternative logic, a const method wouldn't be able to modify anything. That is called a "pure function," a concept which doesn't exist in current standard C++.
You are calling foo on object, not on this.
Since object is declared as an X&, in a constant CX, it is actually an X& const (which is not the same as const X&) allowing you to call non const methods on it.
One helpful way of thinking about it might be that your X object is not a member of CX at all.