4

In the book Effective C++, Item 27

class Widget {
public:
explicit Widget(int size);
...
};
void doSomeWork(const Widget& w);
doSomeWork(Widget(15)); // create Widget from int
                        // with function-style cast

I'm not sure exactly what is happening when doSomeWork is called. I think the parameter w of function doSomeWork is initialized by another Widget object using copy constructor, but where is the other Widget object? Is it a temporary object created by casting as indicated by the comments? Can anyone tell me in details what have been called when doSomeWork function parameter is initialized?

Yu Hao
  • 119,891
  • 44
  • 235
  • 294
Sherry He
  • 43
  • 4

1 Answers1

2

The parameter, w, of function doSomeWork is a Widget that you have created as a parameter in the line

doSomeWork(Widget(15));

doSomeWork expected a Widget and one has been explicitly supplied using the constructor you have listed. No compiler supplied copy constructor is used because the doSomeWork(const Widget &w) signature uses pass by reference semantics.

Just one object is constructed, although pass-by-value could have been used and clever modern compilers would defer the construction to the method's scope to avoid duplicated construction.

John
  • 6,433
  • 7
  • 47
  • 82
  • Thanks for pointing out, yes this is pass by reference, so no copy constructor is involved. So can I say what happens is: const Widget& w=Widget(15) when the function is called?parameter w is initialized with an object created by Widget(15), there is no temporary object generated here. – Sherry He Feb 27 '15 at 17:46
  • Yes, I was just adding pass-by-value is often optimized away by compilers. In the case of the code you have posted just one object is created. See http://stackoverflow.com/questions/24828074/passing-rvalue-reference-to-const-lvalue-reference-paremeter for a discussion on pass-by-reference and rvalues – John Feb 27 '15 at 18:16
  • One more question: how about statement `Widget w=Widget(15);` in this case is a temporary object created first by Widget(15), then w is initialized by the copy constructor? – Sherry He Feb 27 '15 at 18:48
  • 1
    I think it depends on compiler support, better ones being smart enough to defer construction until the scope of `w`. While your example is clearly contrived to create 2 objects and test this idea it is obviously human-fixable. The compiler optimisation is called copy_elision http://en.cppreference.com/w/cpp/language/copy_elision – John Feb 27 '15 at 23:42