Thread: Copy constructor

  1. #16
    Registered User
    Join Date
    Nov 2005
    Posts
    95

    Still more qustions

    I added to same code a function test3.

    Code:
    #include <cstdlib>
    #include <iostream>
    
    using namespace std;
    
    
    class strings 
       {
       char   str[256];
    public : 
       strings(const char *s)
          {
          strcpy(str, s);
          }
       strings(const strings &s)
          {
          cout << "copy constructor  = " << s.str << endl;
          strcpy(str, s.str);
          }
        ~strings(void)
          {
          cout << "Destructing string   " << str << endl;
          }
       void test1(const strings Obj1)
          {
          cout << "in test1 " << Obj1.str << endl;
          }
       strings test2(const strings Obj2)
          {
          cout << "in test2 " << Obj2.str << endl;
          return(Obj2);
          }
       strings test3(void)
          {
          strings tmp("GoodBye");
          return(tmp);
          }
    };
    
    int main(int argc, char *argv[])
    {
    strings  s1("Hellow world");
    
    cout << "Calling test1 : " << endl; 
    s1.test1(s1);
    cout << "\n\nCalling test2" << endl; 
    s1.test2(s1);
    // I added a call to test3.
    cout << "\n\nCalling test3" << endl; 
    s1 = s1.test3();
    
    
    system("PAUSE");
    return EXIT_SUCCESS;
    }
    Begin the ouput :
    Calling test1 :
    copy constructor = Hellow world
    in test1 Hellow world
    Destructing string Hellow world


    Calling test2
    copy constructor = Hellow world
    in test2 Hellow world
    copy constructor = Hellow world
    Destructing string Hellow world
    Destructing string Hellow world


    Calling test3
    Destructing string GoodBye
    Press any key to continue . . .
    End output.


    So why is the copy constructo is not called for the return value from test3 ?

    Thanks in advance.

  2. #17
    C++ Witch laserlight's Avatar
    Join Date
    Oct 2003
    Location
    Singapore
    Posts
    28,413
    Code:
    s1 = s1.test3();
    This does not use the copy constructor, but the copy assignment operator. You did not provide a copy assignment operator, so the compiler provided one for you. Since you have a copy constructor, it probably is a good idea to have a copy assignment operator that matches its behaviour.
    Quote Originally Posted by Bjarne Stroustrup (2000-10-14)
    I get maybe two dozen requests for help with some sort of programming or design problem every day. Most have more sense than to send me hundreds of lines of code. If they do, I ask them to find the smallest example that exhibits the problem and send me that. Mostly, they then find the error themselves. "Finding the smallest program that demonstrates the error" is a powerful debugging tool.
    Look up a C++ Reference and learn How To Ask Questions The Smart Way

  3. #18
    Registered User
    Join Date
    Nov 2005
    Posts
    95

    Then why doe'nt it compile

    Quote Originally Posted by laserlight
    This does not use the copy constructor, but the copy assignment operator.
    I copied the same code, but this time the copy constructor is private. If we are not using the copy constructor then why does it is not compile ?

    Code:
    #include <cstdlib>
    #include <iostream>
    #include <fstream>
    
    using namespace std;
    
    class strings 
       {
       char   str[256];
    public : 
       strings(const char *s)
          {
          strcpy(str, s);
          }
    private:  // Now the class cant access the copy constructor !
       strings(const strings &s)
          {
          cout << "copy constructor  = " << s.str << endl;
          strcpy(str, s.str);
          }
    public:
        ~strings(void)
          {
          cout << "Destructing string   " << str << endl;
          }
       void test1(const strings Obj1)
          {
          cout << "in test1 " << Obj1.str << endl;
          }
       strings test2(const strings Obj2)
          {
          cout << "in test2 " << Obj2.str << endl;
          return(Obj2);
          }
       strings test3(void)
          {
          strings tmp("GoodBye");
          return(tmp);
          }
    };
    
    int main(int argc, char *argv[])
    {
    strings  s1("Hellow world");
    
    // cout << "Calling test1 : " << endl; 
    // s1.test1(s1);
    // cout << "\n\nCalling test2" << endl; 
    // s1.test2(s1);
    cout << "\n\nCalling test3" << endl; 
    s1 = s1.test3();
    
    
    system("PAUSE");
    return EXIT_SUCCESS;
    }
    The errors are :

    17 E:\learncpp\copy_const\main.cpp `strings::strings(const strings&)' is private

    51 E:\learncpp\copy_const\main.cpp within this context


    line 51 is "s1 = s1.test3();"

  4. #19
    Cat without Hat CornedBee's Avatar
    Join Date
    Apr 2003
    Posts
    8,895
    You need, in theory, the copy constructor to return tmp from test3. Optmization gets rid of this copy, but optimization is not allowed to change legality: if the original program failed to compile, then the optimized program must fail, too.
    All the buzzt!
    CornedBee

    "There is not now, nor has there ever been, nor will there ever be, any programming language in which it is the least bit difficult to write bad code."
    - Flon's Law

  5. #20
    Registered User
    Join Date
    Aug 2005
    Location
    Austria
    Posts
    1,990
    compiles and runs fine ( using g++ )
    my output:
    Code:
    Calling test3
    Destructing string   GoodBye
    sh: line 1: PAUSE: command not found
    Destructing string   GoodBye
    Kurt

  6. #21
    Cat without Hat CornedBee's Avatar
    Join Date
    Apr 2003
    Posts
    8,895
    Well, it didn't compile for me ... also g++. Did you test the latest code?
    All the buzzt!
    CornedBee

    "There is not now, nor has there ever been, nor will there ever be, any programming language in which it is the least bit difficult to write bad code."
    - Flon's Law

  7. #22
    Registered User
    Join Date
    Aug 2005
    Location
    Austria
    Posts
    1,990
    Yes the latest ( with private copy constructor ) . using g++ (GCC) 3.3.5
    Kurt

  8. #23
    Cat without Hat CornedBee's Avatar
    Join Date
    Apr 2003
    Posts
    8,895
    3.4.4 here
    All the buzzt!
    CornedBee

    "There is not now, nor has there ever been, nor will there ever be, any programming language in which it is the least bit difficult to write bad code."
    - Flon's Law

  9. #24
    Registered User
    Join Date
    Nov 2005
    Posts
    95

    Now I am really at lost

    Well, it did'nt compile on bloodshed 4.9.9.2. With all optimization turned off !!!
    But I got the same results as Zuk on RedHot 8 with g++ 3.2

    e.g :

    Calling test3
    Destructing string GoodBye
    sh: line 1: PAUSE: command not found
    Destructing string GoodBye


    I quote from "The c++ programming language third edition"
    by BJARNE STROUSTRUP.
    page 221
    The copy constructor ( generated by the compiler or by the programer ) is called in four cases :
    a) initialzing variable ( point p2 = p1)
    b) passing a function by value.
    c) return from function by value.
    d) by exceptions.

    So, why dont I see the call to the copy constructor ?

  10. #25
    Cat without Hat CornedBee's Avatar
    Join Date
    Apr 2003
    Posts
    8,895
    It's optimized away. There's an unnamed temporary object, the return value of func3, which is created as a copy of the variable tmp within func3. But the C++ standard explicitely allows optimizing away unnamed temporary objects, even if the copy constructor and destructor have side effects, so that's just what g++ does. It seems that g++ < 3.4 doesn't even bother to check if the copy constructor is accessible in that case. This seems to have been seen as a bug, so it was changed in 3.4.
    All the buzzt!
    CornedBee

    "There is not now, nor has there ever been, nor will there ever be, any programming language in which it is the least bit difficult to write bad code."
    - Flon's Law

  11. #26
    Registered User
    Join Date
    Nov 2005
    Posts
    95

    So , what about test2 ?

    Quote Originally Posted by CornedBee
    It's optimized away. There's an unnamed temporary object, the return value of func3, which is created as a copy of the variable tmp within func3.
    If so, why dosen't he optimized away (the unnamed temporary object ) in the case of the fucntion strings::test2 ?

    The only diffrence between strings::test2 and strings::test3 is that strings::test2 recives parameter and strings::test3 recives void.

  12. #27
    Registered User
    Join Date
    Jun 2005
    Posts
    6,815
    Presumably because strings2::test returns a copy of it's argument and you've used a "return (Obj2);" style which generally forces creation of a copy of Obj2 to return it over and above what is implied by returning it from the function. While, technically, a compiler is allowed to optimise out temporaries even in cases like this, keep in mind it is not required to. I'd guess the authors of g++ have decided not to eliminate temporaries in cases where the code does things that suggest the programmer is deliberately jumping through hoops to create a temporary. You may also find that tweaking optimisation settings will eliminate the temporary in this case as well.

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. illegal copy constructor required?
    By ichijoji in forum C++ Programming
    Replies: 1
    Last Post: 03-08-2005, 06:27 PM
  2. Linked list copy constructor issue
    By Craptastic! in forum C++ Programming
    Replies: 1
    Last Post: 08-03-2003, 08:30 PM
  3. copy constructor
    By Eber Kain in forum C++ Programming
    Replies: 1
    Last Post: 09-30-2002, 05:03 PM
  4. Quick ? on copy constructor
    By Traveller in forum C++ Programming
    Replies: 3
    Last Post: 05-03-2002, 10:31 AM
  5. Using strings with the copy constructor
    By Unregistered in forum C++ Programming
    Replies: 3
    Last Post: 08-29-2001, 03:04 PM