1

I have a question about the following code:

let's say I have a class P that has a copy constructor and a regular constructor the receives one string value.

I have the following code:

P doSomething(){
   P p("myValue");
   return p;
}

int main(){
    P m=doSomething();
    return 1;
}
  1. why isn't copy constructor invoked at the return p of the doSomething() function?
  2. the call P m=doSomething() - does it suppose to call the copy constructor or the operator=?
  3. in case it's operator =, what is the difference of this code and the following:

    P new_val=("newVal");
    p m=new_val;
    

(i know here the call is for copy constructor)

Thanks, Mary

Shahbaz
  • 46,337
  • 19
  • 116
  • 182
mary
  • 869
  • 5
  • 13
  • 26
  • possible duplicate of [Why has the destructor been called only once?](http://stackoverflow.com/questions/6422114/why-has-the-destructor-been-called-only-once) – Šimon Tóth Sep 21 '11 at 09:12
  • Can you post your code for copy constructor defined in `class P`? – cpx Sep 21 '11 at 09:17
  • On initialization of a variable, always copy constructor is used, even though you are writing `=`. About why it's not used in your example, could be that the compiler has optimized your code? – Shahbaz Sep 21 '11 at 09:20
  • my copy cosntructor is: P (const P & other):val(other.val){} what meant in the assignment is: P m("ffff"); P t=m; as i understand here there is a call for copy constructor what I'm trying to understand why in the code p m=doSomething(); there is no call. – mary Sep 21 '11 at 09:39

3 Answers3

2
  • why isn't copy constructor invoked at the return p of the doSomething() function?

The standard allows this copy to be elided. Google for [N]RVO. On certain compilers this happens only when optimizing, on others it is part of the calling conventions and thus happens always.

  • the call P m=doSomething() - does it suppose to call the copy constructor or the operator=?

T t = x; is "syntactic sugar" (in the sense that the T(x) is happening implicitly) for T t(T(x)) and thus has -- despite the = -- nothing to do with operator=. Note that also here the additional temporary may be elided, thus no copy ctor is called.

  • in case it's operator =, what is the difference of this code and the following:

This code makes no sense, what did you really mean?

P new=("newVal");
p m=new;
PlasmaHH
  • 15,673
  • 5
  • 44
  • 57
  • Re point 2, it's not quite syntactic sugar: the conversion in `T t = x` is implicit (and `explicit` constructors will not be considered); the conversion in your rewrite is explicit. (It's actually possible to write code where both would be legal, but have different semantics. Such code is probably best avoided, however.) – James Kanze Sep 21 '11 at 09:28
  • Copy-initialization and direct initialization aren't entirely equivalent. The latter works even with an `explicit` copy constructor, the former doesn't. – Kerrek SB Sep 21 '11 at 09:32
  • @JamesKanze: therefore the quotes around it, I try to make it a bit cleared in the answer. – PlasmaHH Sep 21 '11 at 09:37
0

I made a small sample for demonstration.

void print(char* text, int ident)
{
    for(int i = 0 ; i < ident ; i++)
    {
        printf("   ");
    } // end for

    fprintf(stdout, text);
    fprintf(stdout, "\n");
    fflush(stdout);
}

class P
{
public:
    char* _str;

    P (P& arg)
    {
        print("copy constructor", 2);
        arg._str = this->_str;
    }

    P (char* str)
    {
        print("constructor", 2);
        _str = str;
    }
};

P doSomething(){
    print("do something - function", 1);
    P p("myValue");
    print("before return p", 1);
    return p;
}

int main(int argc, char* argv[])
{
    print("start", 0);
    P m=doSomething();
    print("stop - call return", 0);
    return 1;
}

this returns

start
   do something - function
      constructor
   before return p
      copy constructor
stop - call return

so copy constructor WILL BE CALLED

-2

1) why isn't copy constructor invoked at the "return p" of the doSomething() function?

it should - try printing something to the console in the copy c-tor to see if it is really running.

2) the call P m=doSomething() - does it suppose to call the copy constructor or the operator=?

should call the operator=. again, use the debug message print from within the method to check

3) in case it's operator =, what is the difference of this code and the following: P new=("newVal"); p m=new; (i know here the call is for copy constructor)

did you miss something on the code snippet? i think it won't compile

NirMH
  • 4,769
  • 3
  • 44
  • 69
  • t should - try printing something to the console in the copy c-tor to see if it is really running. - I did, it doesn't print anything – mary Sep 21 '11 at 09:46