I'm having the below method with multiple const keywords. why are they used?
const int* MyClass::getvalue(const int input) const
if returning a pointer from a method, what are the ways to restrict the user from changing the pointer value and pointer itself?
First of all, having the return type for a value (as opposed to a reference or a pointer) being const is rather useless. The caller of the function can still copy the value to a non-constant variable anyway. For a reference or a pointer, it means that the referenced/pointed to object can not be modified. It can still be copied to a non-constant object though.
The argument being const means that the function can not change the argument. It is partly informational, partly helps the compiler choose optimizations, and for references or pointers means that whatever is referenced/pointed to can't be modified. For references there's also the semantic that you can pass temporary objects to the function.
The last const is for the function itself, and makes it so that the function can only be called on const objects. If you have a non-const MyClass object, this function can't be called on it. This const is part of the function signature, together with the function name and its argument types. That means you can have two overloaded functions with the same name and arguments, one being const qualified and one not.
I'm having the below method with multiple const keywords. why are they used?
const int MyClass::getvalue(const int input) const
^
This makes the return value const. There is no reason to use a return by const value. Some compilers will warn if you use const here. Note that conversely, a reference or a pointer to const object would be reasonable.
const int MyClass::getvalue(const int input) const
^
This makes the argument const. Whether a value argument is const or not makes little difference. A minor advantage of const is that you can know from the declaration that the local object won't change throughout the function, which can be helpful if the function is complex.
const int MyClass::getvalue(const int input) const
^
This makes a member function const. This allows the member function to be called on const instances of the class, but also prevents the function from modifying non-mutable members of the object.
if returning a pointer from a method, what are the ways to restrict the user from changing the pointer value and pointer itself?
There is no way of restricting the user from changing the value of a pointer object that you've returned to them, and there is never a need to do so.
You can restrict the user from modifying the pointed object by returning a pointer to const.
The last const specifies that getvalue() won't change the instance of MyClass it is called upon.
const int input declares a parameter of type int to the function getvalue() specified as const. Its value cannot be changed inside the function.
In the return type const is quite meaningless since the returned value can be assigned to a non-const-qualified int without problem.
what are the ways to restrict the user from changing the pointer value and pointer itself?
Read declarations backwards:
int const * const foo; // foo is a constant pointer to a constant int
int * const bar; // bar is a constant pointer to a int
int const * qux; // qux is a pointer to a constant int
Related
Please refer to this page and go down to the Example.
This is a demonstration about usage of
struct type {
type() :i(3) {}
void m1(int v) const {
// this->i = v; // compile error: this is a pointer to const
const_cast<type*>(this)->i = v; // OK as long as the type object isn't const
}
int i;
};
const here means that m1 could not modify type's member variables. I can't understand why const_cast modify the constness of this. I mean, this pointer points to current type object, not the i itself.
Why not:
const_cast<int>((this)->i) = v;
May I say when one of member function use a const qualifier, the whole object and all member variables become const? Why this is const pointer?
I can't understand why const_cast modify the constness of this
It doesn't. You could say it creates another temporary pointer, which is not a pointer to a const type, but contains the same address as this. It then uses that pointer to access i.
Why not const_cast<int>((this)->i)
You could do something like this, but you need a cast to a reference, not a plain integer.
const_cast<int&>(i) = v; // this-> omitted for brevity
Same caveats apply as any modification of i if this points at an object that is really const.
May I say when one of member function use a const modifier, the whole object and all member variables become const? Why this is const pointer?
Yes. The const qualifier on the member function means that this's pointee type is type const. And all members (which are not mutable) are also const for any access via this.
I have written following 3 functions in C++. Kindly explain me how all return types are different? And how the return values will be stored in Memory? I know const keyword applies to whatever is on immediate left but i need more explanation.
const int* sample1();
int* const sample2();
int const* sample3();
const int* sample1();
int const* sample3();
These functions are identical. They return pointer to constant memory (this memory cannot be changed via this pointer). But we can change pointer itself. Increment it for example.
int* const sample2();
This function returns constant pointer to non-constant memory. We cannot change pointer itself, but we can change the memory it is point.
const does not have to apply to whatever is on immediate right. For example
class Foo
{
void Bar() const;
int var;
}
This will will ban the function Bar in Foo to alter any member variables in the object.
Besides this us2012's comment sums it all up.
I might be totally of but this seems like a school assignment or something?
I would like to return a pointer to an array owned by a class. However, I do not want to allow users to modify that data or pointer. According to how I understand things you need return a constant pointer to constant data using the following syntax.
const Type *const Class::Method() {
return this->data_;
}
However gcc gives the following warning when compiling.
warning: type qualifiers ignored on function return type
Why is this warning provided by gcc? What does it mean? If this is not the right syntax for what I want, what is?
The warning you get is because the final const is overlooked. Take it off and you're set.
You don't need to return a const pointer to const data, just a pointer to const data (which is const Type*). Just as it doesn't make sense to return a const int, it doesn't make sense to return a T* const, because as soon as the value is assigned to a new variable, that const is discarded.
The top level const is ignored for built-in types. As there is a rule in C++[3.14p4]: class and array prvalues can have cv-qualified types; other prvalues always have cv-unqualified types.. In your case const Type* const, the top level const making the pointer const is ignored.
You could add const to the end: const Type * Class::Method() const {...}. This would prevent the pointer from being modified inside the member function. However, since the member function returns prvalue which is non-modifiable, it is not necessary to do this to prevent modification of the pointer member outside of the class (and this is also the reason why this rule exists in C++). It may be useful when you want to call the function with a constant reference to a Class object, etc., but for what you are doing, this doesn't seem necessary.
First const is right, the second const does not make any sense. Just look at this example:
const int foo();
int a = foo();
The fact if foo returns const int or just int does not change anything in this case. Same for Type *.
I'm struggling to get my head around the differences between the various places you can put 'const' on a function declaration in c++.
What is the difference between const at the beginning:
const int MyClass::showName(string id){
...
}
And const at the end like:
int MyClass::showName(string id) const{
...
}
Also, what is the result of having const both at the beginning and at the end like this:
const int MyClass::showName(string id) const{
...
}
const int MyClass::showName(string id) returns a const int object. So the calling code can not change the returned int. If the calling code is like const int a = m.showName("id"); a = 10; then it will be marked as a compiler error. However, as noted by #David Heffernan below, since the integer is returned by copy the calling code is not obliged to use const int. It can very well declare int as the return type and modify it. Since the object is returned by copy, it doesn't make much sense to declare the return type as const int.
int MyClass::showName(string id) const tells that the method showName is a const member function. A const member function is the one which does not modify any member variables of the class (unless they are marked as mutable). So if you have member variable int m_a in class MyClass and if you try to do m_a = 10; inside showName you will get a compiler error.
Third is the combination of the above two cases.
The const attached to the return value applies to the return value. Since the return value is copied it's a pointless declaration and it makes no difference whether or not you include it.
The const after the parameter list means that the function does not modify any state of the object that is not marked as mutable. This is a const member function and if you have a const object the compiler will not allow you to call non-const member functions on a const object.
There is no interaction between these two uses of const - they are completely independent constructs
The difference is that the const applies to different things.
This says that showName returns a constant int value -- one that is immutable. Of course since the int is returned by value the presence of const here does not play any role.
const int MyClass::showName(string id)
And this says that showName does not modify the observable state of MyClass (technically: it does not modify any member that is not declared mutable), and therefore you are allowed to call it on a value of type const MyClass.
int MyClass::showName(string id) const
If you use both consts then both of the above apply.
Questions like this tend to strengthen my resolve to follow the advice of Dan Saks as outlined in this "Conversations with a Guru" article: http://www.drdobbs.com/conversationsa-midsummer-nights-madness/184403835 .
In particular it deals with how the placement of const changes things. (*) I realize that I am extremely unlikely to convert anyone from writing const int ... to int const ..., but that said, there is one reason I prefer to do the latter.
(*) incuding a note that swapping the const with the type declaration at the very start is the one change that has no effect.
It makes for very easy readability, because for any instance of the word
const in a declaration, everything to the left of it is the type of what is const, and everything to the right is what actually is const.
Consider a declaration like:
int const * * const pointerToPointer;
The first const states that the integers at the end of the pointer chain are const, and they are to be found at * * const pointerToPointer. Meanwhile the second one states that an object of type pointer to pointer to const int is also const and that this object is pointerToPointer.
In the OP's case:
int const MyClass::showName(string id){
...
}
The type of what is const is int, and what is const is the return value from the function.
Meanwhile:
int MyClass::showName(string id) const {
...
}
Here the type of what is const is function(string) returning int, and what is const is the function itself, i.e. the function body.
I apologize if this has been asked, but how do I create a member function in c++ that returns a pointer in the following scenerios:
1. The returned pointer is constant, but the junk inside can be modified.
2. The junk inside is constant but the returned pointer can be modified.
3. Neither the junk, nor the pointer can be modified.
Is it like so:
int *const func() const
const int* func() const
const int * const func() const
All of the tutorials I've read don't cover this distinction.
Side note:
If my method is declared const then the tutorials say that I'm stating that I won't modify the parameters.. But this is not clear enough for me in the case when a parameter is a pointer. Do my parameters need to be like:
a. void func(const int* const x) const;
b. void func(const int* x) const;
c. void func(const int* const x) const;
I don't know what book you have read, but if you mark a method const it means that this will be of type const MyClass* instead of MyClass*, which in its turn means that you cannot change nonstatic data members that are not declared mutable, nor can you call any non-const methods on this.
Now for the return value.
1 . int * const func () const
The function is constant, and the returned pointer is constant but the 'junk inside' can be modified. However, I see no point in returning a const pointer because the ultimate function call will be an rvalue, and rvalues of non-class type cannot be const, meaning that const will be ignored anyway
2 . const int* func () const
This is a useful thing. The "junk inside" cannot be modified
3 . const int * const func() const
semantically almost the same as 2, due to reasons in 1.
HTH
Some uses of const don't really make much sense.
Suppose you have the following function:
void myFunction (const int value);
The const tells the compiler that value must not change inside the function. This information does not have any value for the caller. It's up to the function itself to decide what to do with the value. For the caller, the following two function definitions behave exactly the same for him:
void myFunction (const int value);
void myFunction (int value);
Because value is passed by value, which means that the function gets a local copy anyway.
On the other hand, if the argument is a reference or a pointer, things become very different.
void myFunction (const MyClass &value);
This tells the caller that value is passed by reference (so behind the screens it's actually a pointer), but the caller promises not to change value.
The same is true for pointers:
void myFunction (const MyClass *value);
We pass a pointer to MyClass (because of performance reasons), but the function promises not to change the value.
If we would write the following:
void myFunction (MyClass * const value);
Then we are back int he first situation. myFunction gets a pointer, which is passed by value, and which is const. Since MyFunction gets a copy of the pointer value, it doesn't matter for the caller whether it is const or not. The most important thing is that myFunction can change the contents of value, because the pointer variable itself is const, but the contents in it isn't.
The same is true for return values:
const double squareRoot(double d);
This doesn't make any sense. squareRoot returns a const double but since this is passed 'by value', and thus needs to be copied to my own local variable, I can do whatever I want with it.
On the other hand:
const Customer *getCustomer(char *name);
Tells me that getCustomer returns me a pointer to a customer, and I am not allowed to change the contents of the customer.
Actually, it would be better to make the char-pointer-contents const as well, since I don't expect the function to change the given string:
const Customer *getCustomer(const char *name);
int *const func() const
You cannot observe the const here except for a few cases
Taking the address of func.
In C++0x, directly calling func with the function-call syntax as a decltype operand, will yield int * const.
This is because you return a pure pointer value, that is to say a pointer value not actually stored in a pointer variable. Such values are not const qualified because they cannot be changed anyway. You cannot say obj.func() = NULL; even if you take away the const. In both cases, the expression obj.func() has
the type int* and is non-modifiable (someone will soon quote the Standard and come up with the term "rvalue").
So in contexts you use the return value you won't be able to figure a difference. Just in cases you refer to the declaration or whole function itself you will notice the difference.
const int* func() const
This is what you usually would do if the body would be something like return &this->intmember;. It does not allow changing the int member by doing *obj.func() = 42;.
const int * const func() const
This is just the combination of the first two :)
Returning a pointer to const makes a lot of sense, but returning a const pointer (you cannot modify) usually adds no value (although some say it can prevent user errors or add compiler optimisation).
That is because the return value belongs to the caller of the function, i.e. it is their own copy so it doesn't really matter if they modify it (to point to something else). The content however does not "belong" to the caller and the implementor of the function may make a contract that it is read-only information.
Const member functions promise not to change the state of the class, although this is not necessarily enforced in reality by the compiler. I am not referring here to const_cast or mutable members so much as the fact that if your class itself contains pointers or references, a const member function turns your pointers into constant pointers but does not make them pointers to const, similarly your references are not turned into references-to-const. If these are components of your class (and such components are often represented by pointers) your functions can change their state.
Mutable members are there for the benefit of allowing your class to change them whilst not changing internal state. These can typically be applied to:
Mutexes that you wish to lock even for reading.
Data that is lazy-loaded, i.e. filled in the first time they are accessed.
Reference-counted objects: You want to increase the reference count if it has another viewer, thus you modify its state just to read it.
const_cast is generally considered a "hack" and is often done when someone else has not written their code properly const-correct. It can have value though in the following situations:
Multiple overloads where one is const and one non-const and the const returns a const-reference and the non-const returns a non-const reference, but otherwise they are the same. Duplicating the code (if it is not a simple data member get) is not a great idea, so implement one in terms of the other and use const_cast to get around the compiler.
Where you want in particular to call the const overload but have a non-const reference. Cast it to const first.
The const method prevents you from modifying the members. In case of pointers, this means you can't reassign the pointer. You can modify the object pointed at by the pointer to your heart's desire.
As the pointer is returned by value (a copy), the caller can't use it to modify the pointer member of the class. Hence adding const to the return value adds nothing.
Things are different if you were to return a reference to the pointer. Now, if the pointer weren't const, this would mean that a function that doesn't have rights to modify a value is granting this right to the caller.
Example:
class X
{
int* p;
public:
int* get_copy_of_pointer() const //the returned value is a copy of this->p
{
*p = 42; //this being const doesn't mean that you can't modify the pointee
//p = 0; //it means you can't modify the pointer's value
return p;
}
int* const& get_reference_to_pointer() const //can't return a reference to non-const pointer
{
return p;
}
};