You are here:

C++/Static Function

Advertisement


Question
QUESTION: Hi Vijayan,
        I need some clarification about static functions. I have basic idea about static function but my doubt is when we are creating object thru static function. That means, invoke the constructor thru static function and returns that object. In that case, copy constructor has to be called or not when returns creating object from static functions?  That is my question...
For eg

#include <iostream.h>


using namespace std;

class Temp
{
  public:
     static Temp make();
     Temp()
     {
     }
     Temp(Temp&)
     {
        cout<<"Copy Construct"<<std::endl;
     }
     Temp& operator=(Temp& T)
     {
        cout<<"Opetator = "<<std::endl;
        return T;
     }
     ~Temp();
     

};

Temp Temp::make()
{
  return Temp();  //While retuns copy constructor been involved or not
}

int main()
{
  Temp T = Temp::make();
  return 0;
}

AFter running the above program, the copy constructor does't get called.. from the below statement
         Temp T = Temp::make();  
Why?  Please clarify.

ANSWER: Temp Temp::make()
{
      return Temp();  //While retuns copy constructor been involved or not
}

int main()
{
      Temp T = Temp::make() ;
      // ...
}

any good compiler would optimize away the creation of an additional object with extra copy. certainly the compiler is 'allowed' to create a temporary, local Temp object, and then copy-construct that object into variable T in main, and then destroy the temporary object.
but in practice C++ compilers don't do that: the return statement will directly construct T in main.
this optimization is called 'return value optimization' or 'RV optimization' for short.

in fact, even if you had written

Temp Temp::make()
{
      Temp a_named_object ;
      return a_named_object ;
}

int main()
{
      Temp T = Temp::make() ;
      // ...
}

the compiler would still optimize away the creation of unnecessary temporary objects, if all the exit points of a function returned the same named object.
this optimization is called 'named return value optimization' or 'NRV optimization' for short.

such optimizations are allowed by the ISO C++ standard (section 12.8/15) and every good compiler (eg. current versions of the GNU and microsoft compilers) would perform these optimizations.

this is what the IS (international standard ISO/IEC 14882) says:

12.8 - Copying class objects

-1- A class object can be copied in two ways, by initialization, function argument passing and for function value return...
Conceptually, these operations are implemented by a copy constructor...

...

-15- Whenever a temporary class object is copied using a copy constructor, and this object and the copy have the same cv-unqualified type, an implementation is permitted to treat the original and the copy as two different ways of referring to the same object and not perform a copy at all, even if the class copy constructor or destructor have side effects. For a function with a class return type, if the expression in the return statement is the name of a local object, and the cv-unqualified type of the local object is the same as the function return type, an implementation is permitted to omit creating the temporary object to hold the function return value, even if the class copy constructor or destructor has side effects. In these cases, the object is destroyed at the later of times when the original and the copy would have been destroyed without the optimization.

[
Example:

   class Thing
   {
       public:
         Thing();
         ~Thing();
         Thing(const Thing&);
         Thing operator=(const Thing&);
         void fun();
   };

   Thing f() { Thing t; return t; }

   int fun()
   {
       Thing t2 = f();
   }
   Here t does not need to be copied when returning from f.
   The return value of f may be constructed directly into the object t2.
]

for more information see:
http://www.parashift.com/c++-faq-lite/ctors.html#faq-10.9
http://blogs.msdn.com/slippman/archive/2004/02/03/66739.aspx
http://msdn.microsoft.com/en-us/library/ms364057(VS.80).aspx
http://www.opensource.apple.com/darwinsource/DevToolsMar2008/gcc_42-5553/gcc/tre




---------- FOLLOW-UP ----------

QUESTION: Hi Vijayan,

Thanks for your answer. So, the optimization has happened only at exit point of functions return the same named object. correct? or When compiler can provide this kind of optimization? What scenrio?

Answer
no, IS 12.8/15 allows this kind of optimization at any place where it recognizes that the following holds:

"Whenever a temporary class object is copied using a copy constructor, and this object and the copy have the same cv-unqualified type, an implementation is permitted to treat the original and the copy as two different ways of referring to the same object and not perform a copy at all"

for example:

int fun()
  {
      const Thing t2 = f() ;
      const Thing t3 = Thing(t2) ;
      //...
  }

the implementation can treat t3 as a "different way of referring to" t2, and not make the copy at all.

RV and NRV optimizations are the most common examples of this kind of optimization; but they need not be the only ones.

C++

All Answers


Answers by Expert:


Ask Experts

Volunteer


vijayan

Expertise

my primary areas of interest are generic and template metaprogramming, STL, algorithms, design patterns and c++11. i would not answer questions about gui and web programming.

Experience

about 15 years or so

Education/Credentials
post graduate engineer

©2016 About.com. All rights reserved.