Thread: Copy constructors; Best practices (and private)

  1. #1
    (?<!re)tired Mario F.'s Avatar
    Join Date
    May 2006
    Location
    Ireland
    Posts
    8,446

    Copy constructors; Best practices (and private)

    Quote Originally Posted by C++ Primer, Lippman and others
    It is usually best to define either implicitly or explicitly the default and copy constructors. The default constructor is synthesized only if there are no other constructors. If the copy constructor is defined, then the default constructor must be defined as well.
    ("must" was made bold by me)

    I have trouble understanding the last phrase. Especially because while studying through this chapter, I've built a class that doesn't implement a default constructor. Maybe that "must" should be read "should". However, I cannot understand why I should (must?) define the default constructor.


    Also, on a related note, is there any instance in which it may make sense to create a private copy constructor but still define it? I cannot fanthom for the life of me, a situation in which I will want only my member functions and friends to make copies.
    Originally Posted by brewbuck:
    Reimplementing a large system in another language to get a 25% performance boost is nonsense. It would be cheaper to just get a computer which is 25% faster.

  2. #2
    Registered User
    Join Date
    Jan 2005
    Posts
    7,366
    It must be defined if you want it to be available.

    >> is there any instance in which it may make sense to create a private copy constructor but still define it?
    I don't know of any examples offhand, but you explained the potential situation yourself. If you only want member functions (perhaps static) and friends to be able to create copies.

  3. #3
    Registered User
    Join Date
    Apr 2006
    Posts
    2,149
    In such a case the defult constructor will not be created for you.
    Thus you must either create one, or create another non-copy constructor to allow you to construct the object.

    If an object only has a copy constructor it can never be used.
    It is too clear and so it is hard to see.
    A dunce once searched for fire with a lighted lantern.
    Had he known what fire was,
    He could have cooked his rice much sooner.

  4. #4
    Registered User Micko's Avatar
    Join Date
    Nov 2003
    Posts
    715
    I really don't understand why word "must" is there.
    Here's an example:
    Code:
    class Test
    {
        int x;
    public:
        Test(const Test& t)
        {
            x = t.x;
        }
        Test(int c)
        {
            x = c;
        }
        
        void show()
        {
            cout << x << endl;
        }     
    };
    
    int main ( ) 
    {
        Test a(10);
        Test b(a);
        b.show();
    
        return 0;
    In this example copy constructor is defined and other constructor that takes int as argument, but default constructor is not defined and it's OK.
    Gotta love the "please fix this for me, but I'm not going to tell you which functions we're allowed to use" posts.
    It's like teaching people to walk by first breaking their legs - muppet teachers! - Salem

  5. #5
    Lurking whiteflags's Avatar
    Join Date
    Apr 2006
    Location
    United States
    Posts
    9,612
    That's only because you didn't try to write Test c; but you could have wrote
    Code:
    Test::Test(int c = 0) {
        x = c;
    }
    Now Test has a constructor for when it has a parameter and when it doesn't.

  6. #6
    Registered User Micko's Avatar
    Join Date
    Nov 2003
    Posts
    715
    Quote Originally Posted by citizen
    That's only because you didn't try to write Test c; but you could have wrote
    Code:
    Test::Test(int c = 0) {
        x = c;
    }
    Now Test has a constructor for when it has a parameter and when it doesn't.
    Of course I didn't try to make object with Test c; because it would be a compiler error since once you define one constructor, all others you need to define manually includeing default. i want to prove with my code that if you define copy constructor you don't need to define DEFAULT constructor as well.
    Gotta love the "please fix this for me, but I'm not going to tell you which functions we're allowed to use" posts.
    It's like teaching people to walk by first breaking their legs - muppet teachers! - Salem

  7. #7
    (?<!re)tired Mario F.'s Avatar
    Join Date
    May 2006
    Location
    Ireland
    Posts
    8,446
    Yes, that was my confusion too. There is no need to define a default constructor as long as some other valid constructor is defined. In other words, what must be defined is some valid constructor. It doesn't necessarily need to be the default constuctor.

    Thanks all. King Mir nailed it.
    Originally Posted by brewbuck:
    Reimplementing a large system in another language to get a 25% performance boost is nonsense. It would be cheaper to just get a computer which is 25% faster.

  8. #8
    semi-colon generator ChaosEngine's Avatar
    Join Date
    Sep 2005
    Location
    Chch, NZ
    Posts
    597
    Quote Originally Posted by Mario F.
    Yes, that was my confusion too. There is no need to define a default constructor as long as some other valid constructor is defined. In other words, what must be defined is some valid constructor. It doesn't necessarily need to be the default constuctor.

    Thanks all. King Mir nailed it.
    yes, he did. but what I think others aren't getting is that if you define a copy constructor you must define another valid constructor.

    Code:
    class Test
    {
    public:
       Test(const Test &rhs) {}
    };
    
    int main()
    {
        Test t(?????); // what goes here? chicken and egg!!
    }
    "I saw a sign that said 'Drink Canada Dry', so I started"
    -- Brendan Behan

    Free Compiler: Visual C++ 2005 Express
    If you program in C++, you need Boost. You should also know how to use the Standard Library (STL). Want to make games? After reading this, I don't like WxWidgets anymore. Want to add some scripting to your App?

  9. #9
    Registered User
    Join Date
    May 2006
    Posts
    903
    Code:
    int main() {
        Test foo;
        Test bar1 = foo; // calls copy constructor
        Test bar2(foo); // calls copy constructor
    }

  10. #10
    semi-colon generator ChaosEngine's Avatar
    Join Date
    Sep 2005
    Location
    Chch, NZ
    Posts
    597
    Quote Originally Posted by Desolation
    Code:
    int main() {
        Test foo;
        Test bar1 = foo; // calls copy constructor
        Test bar2(foo); // calls copy constructor
    }
    if there's a point there, I've missed it.
    "I saw a sign that said 'Drink Canada Dry', so I started"
    -- Brendan Behan

    Free Compiler: Visual C++ 2005 Express
    If you program in C++, you need Boost. You should also know how to use the Standard Library (STL). Want to make games? After reading this, I don't like WxWidgets anymore. Want to add some scripting to your App?

  11. #11
    Registered User
    Join Date
    May 2006
    Posts
    903
    Nevermind, I thought your question in the code was an actual question.

  12. #12
    Registered User
    Join Date
    Jan 2005
    Posts
    7,366
    I'm guessing the quote was from a context discussing whether a default constructor is provided by the compiler or not and as I said before, the "must" means "must, if you want one". I didn't see that quote in the 3rd version of the book. I assume you are using the 4th edition?

  13. #13
    (?<!re)tired Mario F.'s Avatar
    Join Date
    May 2006
    Location
    Ireland
    Posts
    8,446
    Well, yes. I should probably have stated this is taken from the 4th edition for those who wished to take a read at the book.

    And yes, you were quiet right. But I believe you can now understand why it still left me in the dark. The quote is outside any context. It is presented in the book as just a note on good practices at the end of the section dealing with copy-constructors.

    However, truth be told I had a duh feeling after King Mir reply. Maybe a little more thinking and I wouldn't have the need to post the question
    Originally Posted by brewbuck:
    Reimplementing a large system in another language to get a 25% performance boost is nonsense. It would be cheaper to just get a computer which is 25% faster.

  14. #14
    Registered User
    Join Date
    Jan 2005
    Posts
    7,366
    If it really is without context, then that should probably be noted in an errata if they have one for that edition yet. Otherwise you might want to report it to the publisher so that it can be re-worded. Without proper context it is just wrong.

  15. #15
    Algorithm Dissector iMalc's Avatar
    Join Date
    Dec 2005
    Location
    New Zealand
    Posts
    6,318
    If you don't define a default constructor, and the compiler can't generate one because you've provided a copy-constructor, then good luck trying to use the class in a std::map, for example.

    Basically, you might not need to use the default constructor, but something else might need it! Not doing so makes your class unnecessarily limited in terms of reuse.

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. read-only data members. A question of good practices
    By Mario F. in forum C++ Programming
    Replies: 11
    Last Post: 06-19-2006, 04:35 AM