0

Can someone please explain the use of const when its being used in function declarations and classes? I understand that if a function returns a const variable/object, then that thing can not be used on the left side of an assignment operator? Is this correct? Also, i noticed that if you were to do:

int x = 1;
int &i = x; 

The above code would not compile unless i were a "constant reference" to the int. For functions, do the arguments passed into the function parameters have to be constant if the parameters are declared constant?

One example of my book has the following code:

const Array &Array::operator=(const Array &right)
{
if (&right != this) //avoid self assignment
  //blah blah
return *this; //enables x = y = z for example
}

Why does this function permit the object Array assignments such as x = y = z but prevents ones like (x = y) = z?? The book's reasoning is "because z cannot be assigned to the const Array reference that's returned by (x = y). But in the first case, doesn't x = y also return a constant Array reference???

Also, when you do assign 1 object of a class to another, the compiler uses member wise assignment unless the the user provides a default copy constructor, in which case THAT is invoked right?

Thankyou so much! Sorry I have a lot of specific questions. I greatly appreciate it.

Kevin Cheng
  • 115
  • 1
  • 4
  • A value of `const`-qualified type cannot be used where a non-`const`-qualified type is expected, like normally on the lhs of an assignment-expression. See http://coliru.stacked-crooked.com/a/71dfb0ed9bc208d6 for an example of mis-definition of op=. – Deduplicator Oct 27 '14 at 02:42
  • The code you said would not compile would indeed compile, why do you think it wouldn't? – RamblingMad Oct 27 '14 at 02:45
  • Before writing "the above would not compile", try compiling it !! – M.M Oct 27 '14 at 03:13

2 Answers2

1

Can someone please explain the use of const when its being used in function declarations and classes?

const on a member function means the function can't modify the non-mutable data members. It also means the function can be called on a const instance of the class, whereas non-const member functions can not.

const can also be used on data members - it means they have to be assigned to in the constructor's initialiser list and can not be modified thereafter (even from non-const member functions).

[int x = 1; int &i = x; would not compile unless...

Yes it does. What you can't do is this: const int x = 1; int &i = x; - you can't do it because such an i would incorrectly facilitate a later assignment ala i = 4; asking to write to the const int x.

permit the object Array assignments such as x = y = z but prevents ones like (x = y) = z?

C++ operator precedence means x = y = z - without parentheses - is equivalent to x = (y = z), so the (y = z) assignment yields a const value that can still be assigned to the non-const object x.

That contrasts with (x = y) = z where (x = y) yields a temporary const value that can't be further assigned to (given Array::operator= is not a const member function, per the rules mentioned above)

Also, when you do assign 1 object of a class to another, the compiler uses member wise assignment unless the the user provides a default copy constructor, in which case THAT is invoked right?

default is the keyword a programmer uses to explicitly ask for a compiler-generated copy constructor, i.e. one that does the member wise assignments. It's when the user provides their own user-defined implementation (or deletes the copy constructor) that the default implementation is not used.

Tony Delroy
  • 102,968
  • 15
  • 177
  • 252
  • Oh, I thought the rules for precedence were from left to right, if the operator is the same? So 1 + 2 + 3 would evaluate as 1 + (2 + 3)? Thanks – Kevin Cheng Oct 27 '14 at 03:14
  • A reference being returned by a function can be used as a lvalue or a rvalue right? ex: cout << integers1[5]; or integers1[5] = 1000; – Kevin Cheng Oct 27 '14 at 03:18
  • @KevinCheng: `1 + 2 + 3` --> `(1 + 2) + 3`... see the linked page's "Associativity" column where it says which operators are "Left-to-Right" and "Right-to-Left", and note that the relevant operators are "Addition and subtraction", not "Unary plus and minus". – Tony Delroy Oct 27 '14 at 03:31
  • *"A reference being returned by a function can be used as a lvalue or a rvalue right? ex: `cout << integers1[5];` or `integers1[5] = 1000;`"* - that's right if the returned reference is not `const`. – Tony Delroy Oct 27 '14 at 03:32
0

Yes, you are correct in assuming that.

const is an indication that the data you have is not mutable, this is just a compiler technique though; assembly has not paradigm of 'const-ness'.

(const_cast is a good example of this)

Where the const is placed on a line is extremely important too, especially for pointers.

e.g.

const int *ptr isn't the same as int const *ptr

That doesn't apply exactly the same to references though, so I guess that was just a bad example.


const is also important when defining class methods. Which methods are available when you get a const& to an object?

Well, this is a well defined case:

#include <iostream>
class shizam{
    public:
        void print() const {std::cout << "const shizam!\n";}
        void print()       {std::cout << "non-const shizam!\n";}
};

Then if later on we have a function:

void print_shazam(const shizam &ref){
    ref.print();
}

That function would print "const shizam!"

but a function

void print_shazam(shizam &ref){
    ref.print();
}

would print "non-const shizam!"

This is important because then the person defining the class can seperate the methods that can modify the class and those that can't; as I said, const is an indication that the data is not mutable.


This example from the same book:

const Array &Array::operator=(const Array &right){
    if(&right != this){ //avoid self assignment
        // blah blah
    }
    return *this; //enables x = y = z for example
}

Has already been discussed here

Community
  • 1
  • 1
RamblingMad
  • 5,332
  • 2
  • 24
  • 48