Thread: Default copy constructor vs. STL containers

  1. #1
    Registered User
    Join Date
    Jun 2010
    Location
    Bakersfield, California
    Posts
    22

    Default copy constructor vs. STL containers

    I've been reading and understand that classes that contain dynamically allocated members will copy only the pointer to these members when using the default constructors. But I've only seen this in the context of using "new", "malloc", etc...

    Are the STL containers immune to this? Or do I still need to provide my own copy and/or assignment constructor?

  2. #2
    Guest Sebastiani's Avatar
    Join Date
    Aug 2001
    Location
    Waterloo, Texas
    Posts
    5,708
    Quote Originally Posted by micahharwell View Post
    I've been reading and understand that classes that contain dynamically allocated members will copy only the pointer to these members when using the default constructors. But I've only seen this in the context of using "new", "malloc", etc...

    Are the STL containers immune to this? Or do I still need to provide my own copy and/or assignment constructor?
    The default copy constructor basically invokes the copy constructor of each member, unless it's a built-in type (int, double, pointers, etc), in which case the underlying bytes are simply copied into the member. In the case of pointers that are "managed" by the object this can be disastrous, as multiple objects are then prone to "free" the object.

    Code:
    #include <iostream>
    
    struct foo
    {
        foo( void )
        {
            data = new int;
        }
        
        ~foo( void )
        {
            std::cout << "foo (" << static_cast< void* >( this ) << ") freeing data (" << data << ")" << std::endl;
            delete data;
        }
        
        int* data;
    };
    
    int main( void )
    {
        foo a, b = a;
    }
    So...yes, you generally need to write your own copy constructor in such a case (or else use a "smart-pointer", or similar).
    Code:
    #include <cmath>
    #include <complex>
    bool euler_flip(bool value)
    {
        return std::pow
        (
            std::complex<float>(std::exp(1.0)), 
            std::complex<float>(0, 1) 
            * std::complex<float>(std::atan(1.0)
            *(1 << (value + 2)))
        ).real() < 0;
    }

  3. #3
    Officially An Architect brewbuck's Avatar
    Join Date
    Mar 2007
    Location
    Portland, OR
    Posts
    7,396
    If you build your data types only from other data types that do the right thing when copied, then you'll never need to write a copy constructor or assignment operator ever.
    Code:
    //try
    //{
    	if (a) do { f( b); } while(1);
    	else   do { f(!b); } while(1);
    //}

  4. #4
    Algorithm Dissector iMalc's Avatar
    Join Date
    Dec 2005
    Location
    New Zealand
    Posts
    6,318
    You are always responsible for making sure that your classes have well-defined copy and assignment behaviour. The only other acceptable option is to prevent use of those things through the standard "private & unimplemented" technique.
    My homepage
    Advice: Take only as directed - If symptoms persist, please see your debugger

    Linus Torvalds: "But it clearly is the only right way. The fact that everybody else does it some other way only means that they are wrong"

  5. #5
    Registered User
    Join Date
    Jun 2010
    Location
    Bakersfield, California
    Posts
    22
    Alrighty! Thanks guys! It's a learning curve, but I'm climbing it - and this board gives me a foothold when I can't find one.

  6. #6
    C++まいる!Cをこわせ!
    Join Date
    Oct 2007
    Location
    Inside my computer
    Posts
    24,654
    Smart pointers can help you avoid having to write logic for copying these members.
    And STL containers are designed so that they are safe to copy. You don't need to worry about those.
    Quote Originally Posted by Adak View Post
    io.h certainly IS included in some modern compilers. It is no longer part of the standard for C, but it is nevertheless, included in the very latest Pelles C versions.
    Quote Originally Posted by Salem View Post
    You mean it's included as a crutch to help ancient programmers limp along without them having to relearn too much.

    Outside of your DOS world, your header file is meaningless.

  7. #7
    Registered User
    Join Date
    Jun 2005
    Posts
    6,815
    Quote Originally Posted by Elysia View Post
    And STL containers are designed so that they are safe to copy.
    .... assuming the objects they contain are safe to copy.

    If an object type does not have a safe copy constructor (eg it contains a pointer to a resource, and no copy constructor and assignment operator to properly copy that resource) putting it in a STL container produces a container that cannot be safely copied either.
    Right 98% of the time, and don't care about the other 3%.

    If I seem grumpy or unhelpful in reply to you, or tell you you need to demonstrate more effort before you can expect help, it is likely you deserve it. Suck it up, Buttercup, and read this, this, and this before posting again.

  8. #8
    Registered User
    Join Date
    Jun 2010
    Location
    Bakersfield, California
    Posts
    22
    Okay. In my application, the only dynamic members are STL containers. It appears that they are "copy safe". Thanks again guys.

  9. #9
    C++まいる!Cをこわせ!
    Join Date
    Oct 2007
    Location
    Inside my computer
    Posts
    24,654
    Quote Originally Posted by grumpy View Post
    .... assuming the objects they contain are safe to copy.
    Erm. Good point.
    It can be said that the STL libraries themselves are safe to copy, but their contents are not. The libraries will invoke the default copy constructor and/or assignment operator when copying them. Therefore, those must be safe for the type you're storing or you will not be able to safely copy containers.
    Quote Originally Posted by Adak View Post
    io.h certainly IS included in some modern compilers. It is no longer part of the standard for C, but it is nevertheless, included in the very latest Pelles C versions.
    Quote Originally Posted by Salem View Post
    You mean it's included as a crutch to help ancient programmers limp along without them having to relearn too much.

    Outside of your DOS world, your header file is meaningless.

  10. #10
    Officially An Architect brewbuck's Avatar
    Join Date
    Mar 2007
    Location
    Portland, OR
    Posts
    7,396
    All of that silliness can be avoided if you ensure that your fundamental types are safe to copy. Copy safety, and for that matter exception safety and resource safety, spring from the lowest level datatypes and percolate upward in the design.

    If you find yourself writing a copy constructor, stop and ask yourself whether you really ought to be changing the lower-level data types to do the right thing instead. The number of low-level types is limited. The number of higher level types is potentially infinite. I prefer to do a finite amount of work, not an infinite amount of it.
    Code:
    //try
    //{
    	if (a) do { f( b); } while(1);
    	else   do { f(!b); } while(1);
    //}

  11. #11
    Registered User
    Join Date
    Jun 2005
    Posts
    6,815
    Quote Originally Posted by brewbuck View Post
    All of that silliness can be avoided if you ensure that your fundamental types are safe to copy. Copy safety, and for that matter exception safety and resource safety, spring from the lowest level datatypes and percolate upward in the design.
    If by "fundamental types" you mean the types that are building blocks of your application, I agree. (Sorry about being picky, but the term could mean many things).

    The only exception I would make is with those types that should not be copied (in which case I declare a private copy constructor and don't implement it). And, whatever I do with a copy constructor, I mirror with an assignment operator.
    Right 98% of the time, and don't care about the other 3%.

    If I seem grumpy or unhelpful in reply to you, or tell you you need to demonstrate more effort before you can expect help, it is likely you deserve it. Suck it up, Buttercup, and read this, this, and this before posting again.

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Prime Number Generator... Help !?!!
    By Halo in forum C++ Programming
    Replies: 9
    Last Post: 10-20-2003, 07:26 PM
  2. include question
    By Wanted420 in forum C++ Programming
    Replies: 8
    Last Post: 10-17-2003, 03:49 AM
  3. copy and erase functions in STL
    By wrr2 in forum C++ Programming
    Replies: 4
    Last Post: 12-23-2002, 02:28 PM
  4. Pointer Elements & STL Containers :: STL
    By kuphryn in forum C++ Programming
    Replies: 2
    Last Post: 09-30-2002, 08:13 PM
  5. STL: element-wise addition of the contents of two containers
    By geophyzzer in forum C++ Programming
    Replies: 4
    Last Post: 06-26-2002, 06:17 PM

Tags for this Thread