0

I have seen many people set their function argument as:

function(const myType &myObj)

I do not understand why they use & after the type?

It seems const is enough to stop the constructor from being called.

So, I wrote the following code and I see no advantage in the result. Can someone explain that?

#include <iostream>
using namespace std;

class myclass
{
public:

    myclass()
    {
        cout<<"constructor is called\n";
    }

    int field;
};

void func1(myclass a)
{
    cout<<"func1: "<<a.field<<"\n";
}


void func2(const myclass a)
{
    cout<<"func2: "<<a.field<<"\n";
}


void func3(const myclass &a)
{
    cout<<"func3: "<<a.field<<"\n";
}

int main ()
{
    myclass obj;
    obj.field=3;
    cout<<"----------------\n";
    func1(obj);
    cout<<"----------------\n";
    func2(obj);
    cout<<"----------------\n";
    func3(obj);
    cout<<"----------------\n";
    return 0;
}

Result:

constructor is called
----------------
func1: 3
----------------
func2: 3
----------------
func3: 3
----------------
NathanOliver
  • 171,901
  • 28
  • 288
  • 402
bastik
  • 11
  • 2
  • This is not about default constructor, it's about [copy constructor](http://en.cppreference.com/w/cpp/language/copy_constructor), which in your case is [generated automatically](http://stackoverflow.com/questions/4172722/what-is-the-rule-of-three). Please take a look at [The Definitive C++ Book Guide and List](http://stackoverflow.com/questions/388242/the-definitive-c-book-guide-and-list) – Ivan Aksamentov - Drop Apr 29 '16 at 12:33
  • `const` has nothing to do with whether a constructor is called – M.M Apr 29 '16 at 12:34

3 Answers3

7

So, I wrote the following code and I see no advantage in the result. Can someone explain that?

The problem is you never set your copy constructor to output anything to see if a copy is made. If we add

myclass( const myclass & foo) : field(foo.field)
{
    cout<<"copy constructor is called\n";
}

The output will be

constructor is called
----------------
copy constructor is called
func1: 3
----------------
copy constructor is called
func2: 3
----------------
func3: 3
----------------

Live Example

As you can see copies are made if you do not pass by reference.


The only difference between

void func1(myclass a)

and

void func2(const myclass a)

Is that a is const in the second example. There really is no reason to do this though; since it is a copy, it doesn't matter if you change it or not. If you have a function that can use a const object, then I suggest passing by const & to avoid copies as long as copying is more expensive than a reference (non-pod types, which are bigger than the size of a pointer).

Charles
  • 1,384
  • 11
  • 18
NathanOliver
  • 171,901
  • 28
  • 288
  • 402
2

It seems const is enough to stop the constructor from being called.

If you use just const and no &, copy constructor is called. Using const & guarantees no new copy of objects are made.

As pointed in the comments below: the reason you are not seeing the output is because you never logged the invocation copy constructors. Putting print in destructor of the class would be perhaps a better idea to see the effect.

Mohit Jain
  • 30,259
  • 8
  • 73
  • 100
  • Most of your answer is talking about copy elision which has nothing at all to do with this question – M.M Apr 29 '16 at 12:37
2

Add in the class members:

myclass(myclass const &)
{
    cout<<"copy constructor is called\n";
}

~myclass()
{
    cout<<"destructor is called\n";
}

and then, after inspecting the new output, re-evaluate your position on what effect the & has.

M.M
  • 138,810
  • 21
  • 208
  • 365