Why is not copy constructor called?

Discussion in 'C++' started by janzon@gmail.com, Oct 13, 2006.

  1. Guest

    Consider the code below. The output is the following two lines:

    0xbfc78090
    0xbfc780a0

    This proves that the variable m in main() is not the very same instance
    of MyClass as temp_m in hello(). Hence (?) m is created as copy of
    temp_m. But the copy constructor is not called. Contradiction. Where am
    I thinking incorrectly?

    #include <iostream>

    using namespace std;

    class MyClass
    {
    public:
    MyClass () {}

    MyClass (const MyClass& m)
    {
    cout << "Copy constructor called!" << endl;
    }
    };

    MyClass hello()
    {
    MyClass temp_m;
    cout << &temp_m << endl;
    return temp_m;
    }

    int main()
    {
    MyClass m;
    m=hello();
    cout << &m <<endl;
    }
     
    , Oct 13, 2006
    #1
    1. Advertising

  2. Pete C Guest

    wrote:
    > Consider the code below. The output is the following two lines:
    >
    > 0xbfc78090
    > 0xbfc780a0
    >
    > This proves that the variable m in main() is not the very same instance
    > of MyClass as temp_m in hello(). Hence (?) m is created as copy of
    > temp_m. But the copy constructor is not called. Contradiction. Where am
    > I thinking incorrectly?


    m is not created as a copy of temp_m. It is default constructed, and
    only later is it assigned to the (temporary) return value of hello(),
    using the compiler-generated assignment operator. To see this, add the
    following to your class definition:

    MyClass &operator=(const MyClass& m)
    {
    cout << "Assignment operator called!" << endl;
    return *this;
    }

    You will see that it is being called. Alternatively, try:

    MyClass m(hello());

    and you will see the results you probably expected the first time
    around.
     
    Pete C, Oct 14, 2006
    #2
    1. Advertising

  3. IR Guest

    wrote:

    > This proves that the variable m in main() is not the very same
    > instance of MyClass as temp_m in hello(). Hence (?) m is created
    > as copy of temp_m. But the copy constructor is not called.
    > Contradiction. Where am I thinking incorrectly?


    > m=hello();


    You are not using the copy constructor, but the assignment operator.

    Try defining in MyClass

    MyClass& operator =(const MyClass& m)
    {
    cout << "Assignment operator called!" << endl;
    }

    OR in main() (to use copy constructor) :

    MyClass m(hello());

    Cheers,

    --
    IR
     
    IR, Oct 14, 2006
    #3
  4. IR Guest

    IR wrote:

    > MyClass& operator =(const MyClass& m)
    > {
    > cout << "Assignment operator called!" << endl;
    > }


    dammit i forgot return *this;
    shame on me

    --
    IR
     
    IR, Oct 14, 2006
    #4
  5. gt8887b Guest

    The code below should not call copy constructor.

    Let's consider you main() again:

    int main()
    {
    MyClass m; //here you construct an instance of MyClass - m
    //the default constructor is used

    //here you first call hello() which constructs another instance of
    MyClass (temp_m)
    //using the default constructor and returns it. The compiler would
    usually avoid constructing
    //a temporary MyClass object to be returned.
    //
    //next step is to assign the return value from hello() to m
    //compiler would use the assignment operator rather then copy
    constructor in this case
    m=hello();



    On Oct 13, 6:29 pm, wrote:
    > Consider the code below. The output is the following two lines:
    >
    > 0xbfc78090
    > 0xbfc780a0
    >
    > This proves that the variable m in main() is not the very same instance
    > of MyClass as temp_m in hello(). Hence (?) m is created as copy of
    > temp_m. But the copy constructor is not called. Contradiction. Where am
    > I thinking incorrectly?
    >
    > #include <iostream>
    >
    > using namespace std;
    >
    > class MyClass
    > {
    > public:
    > MyClass () {}
    >
    > MyClass (const MyClass& m)
    > {
    > cout << "Copy constructor called!" << endl;
    > }
    >
    > };MyClass hello()
    > {
    > MyClass temp_m;
    > cout << &temp_m << endl;
    > return temp_m;
    >
    > }int main()
    > {
    > MyClass m;
    > m=hello();
    > cout << &m <<endl;
    >
    >
    >
    > }- Hide quoted text -- Show quoted text -
     
    gt8887b, Oct 14, 2006
    #5
  6. * :
    > Consider the code below. The output is the following two lines:
    >
    > 0xbfc78090
    > 0xbfc780a0
    >
    > This proves that the variable m in main() is not the very same instance
    > of MyClass as temp_m in hello(). Hence (?) m is created as copy of
    > temp_m. But the copy constructor is not called. Contradiction. Where am
    > I thinking incorrectly?
    >
    > #include <iostream>
    >
    > using namespace std;
    >
    > class MyClass
    > {
    > public:
    > MyClass () {}
    >
    > MyClass (const MyClass& m)
    > {
    > cout << "Copy constructor called!" << endl;
    > }
    > };
    >
    > MyClass hello()
    > {
    > MyClass temp_m;
    > cout << &temp_m << endl;
    > return temp_m;
    > }
    >
    > int main()
    > {
    > MyClass m;
    > m=hello();
    > cout << &m <<endl;
    > }


    Well, there are two possible misconceptions involved.

    First, the '=' in the statement 'm=hello();' is an /assignment/,
    invoking the assignment operator, not the copy constructor. The
    difference between assignment and copy construction is that assignment
    changes the member values of some existing object (perhaps deallocating
    already allocated memory), whereas copy construction turns a chunk of
    raw, uninitialized memory into an object, a copy. Perhaps you knew
    that, but the formulation "creates as a copy of" seems to indicate that
    this is indeed the basic misconception; if you'd written 'MyClass m =
    hello();' then the "=" would instead denote copy construction.

    Second, the compiler is allowed to optimize away copy construction in
    certain situations, /regardless of whether the copy constructor has side
    effects or not/. The copy constructor is very very special, in that the
    compiler, in these relevant situations, is allowed to assume that what
    the copy constructor does is to actually construct a perfect copy, and
    nothing else whatsoever. These situations include the 'MyClass m =
    hello();' initialization, as well as the call to 'hello()' itself (where
    this optimization is known as RVO, Return Value Optimization).

    This also means that C++ tests that ask you to count the number of copy
    constructor calls in a piece of code, ending up with some exact number,
    are generally tests made by incompetents (although in some pieces of
    code you can be sure of the number of calls).

    And unfortunately that includes most C++ tests, even some that cost $$$.

    Hth.,

    - Alf


    --
    A: Because it messes up the order in which people normally read text.
    Q: Why is it such a bad thing?
    A: Top-posting.
    Q: What is the most annoying thing on usenet and in e-mail?
     
    Alf P. Steinbach, Oct 14, 2006
    #6
  7. IR Guest

    Alf P. Steinbach wrote:

    > if you'd written 'MyClass m = hello();' then
    > the "=" would instead denote copy construction.


    Interesting... I believe I once read an article on this topic, which
    conclusion (as far a I recall) was:

    Always use explicit copy construction
    MyClass m(hello());
    rather than assignment
    MyClass m = hello();
    as the latter translates to
    MyClass m; m = hello();
    which obviously calls an useless default constructor.

    Alf (or anyone else), could you shed some light on this? Your
    statement kinda confuses me, is this explicitely part of the standard?

    Thanks in advance.

    --
    IR
     
    IR, Oct 14, 2006
    #7
  8. * IR:
    > Alf P. Steinbach wrote:
    >
    >> if you'd written 'MyClass m = hello();' then
    >> the "=" would instead denote copy construction.

    >
    > Interesting... I believe I once read an article on this topic, which
    > conclusion (as far a I recall) was:
    >
    > Always use explicit copy construction
    > MyClass m(hello());
    > rather than assignment
    > MyClass m = hello();
    > as the latter translates to
    > MyClass m; m = hello();
    > which obviously calls an useless default constructor.
    >
    > Alf (or anyone else), could you shed some light on this?


    Yes, I did. ;-)

    An initialization with "=" is formally a copy initialization, using the
    copy constructor (which call can, however, be optimized away).

    It's not translated to default construction plus assignment: a compiler
    that did that (none such exist as far as I know) would be in flagrant
    breach of the rules of the standard.


    > Your
    > statement kinda confuses me, is this explicitely part of the standard?


    Yes.

    --
    A: Because it messes up the order in which people normally read text.
    Q: Why is it such a bad thing?
    A: Top-posting.
    Q: What is the most annoying thing on usenet and in e-mail?
     
    Alf P. Steinbach, Oct 14, 2006
    #8
  9. IR Guest

    Alf P. Steinbach wrote:

    > An initialization with "=" is formally a copy initialization,
    > using the copy constructor (which call can, however, be optimized
    > away).
    >
    > It's not translated to default construction plus assignment: a
    > compiler that did that (none such exist as far as I know) would be
    > in flagrant breach of the rules of the standard.


    Oh well, I just tested it in VS8. You are right (of course).

    So, either the author of the article was wrong, or I have the memory
    of a goldfish (which is the most likely of the two alternatives...)

    In other words, my bad.
    At least I'll have learned something today :)

    --
    IR
     
    IR, Oct 14, 2006
    #9
  10. * IR:
    >
    > [...], or I have the memory
    > of a goldfish (which is the most likely of the two alternatives...)


    See e.g. <url: http://www.abc.net.au/science/k2/moments/s1179348.htm>:
    <quote>
    The fish that knew their tank remembered the trawling net so well,
    that they could escape it in a follow-up study some 11 months later.

    By the way, 11 months is nearly one third of his fish's 3-year
    lifespan. That's a very long time to remember something that has
    happened to you only once, and in human terms, about 25 years ago.

    Yoichi Oda of Osaka University in Japan has spent years studying the
    fine details of memory in goldfish - and he's also convinced that
    goldfish have a good memory.
    </quote>

    See also e.g. Yahoo! Answers "How intelligent are goldfish?" at <url:
    http://uk.answers.yahoo.com/question/index?qid=20061005044222AA8AcA0>:
    <quote>
    Goldfish and the 3 second memory span:
    The Myth Busters TV show proved this one a myth. They taught fish to
    swim through a maze, showing that their time got faster and faster.
    Thus proving they remembered where the holes were.
    </quote>

    Thus, in conclusion, if you actually have the memory (that would be
    analogous to the memory) of a goldfish, then you have a very good memory
    indeed, able to remember trivial details a third of a lifespan later.

    Anyway, let's stop the goldfish bashing in clc++!

    --
    A: Because it messes up the order in which people normally read text.
    Q: Why is it such a bad thing?
    A: Top-posting.
    Q: What is the most annoying thing on usenet and in e-mail?
     
    Alf P. Steinbach, Oct 14, 2006
    #10
    1. Advertising

Want to reply to this thread or ask your own question?

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. Apricot
    Replies:
    4
    Views:
    546
    velthuijsen
    Apr 16, 2004
  2. Tom Widmer
    Replies:
    1
    Views:
    518
    Victor Bazarov
    Nov 17, 2004
  3. Mr. SweatyFinger
    Replies:
    2
    Views:
    2,077
    Smokey Grindel
    Dec 2, 2006
  4. suresh
    Replies:
    2
    Views:
    394
    Andrey Tarasevich
    Apr 15, 2008
  5. cinsk
    Replies:
    35
    Views:
    2,657
    James Kanze
    Oct 11, 2010
Loading...

Share This Page