Necessary for copy constructor??

Discussion in 'C++' started by qazmlp1209@rediffmail.com, Jan 11, 2007.

  1. Guest

    Will the following program cause any problem, because of the missing
    explicit copy constructor for the 'test' class?

    #include <vector>
    #include <iostream>

    class test
    {
    char* cPtr ;

    public:

    test()
    {
    cPtr = new char[10] ;
    }

    ~test()
    {
    delete cPtr ;
    }
    } ;


    int main()
    {
    std::vector< test*> vecTest ;

    test* testPtr = new test() ;

    vecTest.push_back( testPtr ) ;

    delete testPtr ;

    vecTest.clear() ;
    }
     
    , Jan 11, 2007
    #1
    1. Advertising

  2. wrote:
    > Will the following program cause any problem, because of the missing
    > explicit copy constructor for the 'test' class?
    >
    > #include <vector>
    > #include <iostream>
    >
    > class test
    > {
    > char* cPtr ;
    >
    > public:
    >
    > test()
    > {
    > cPtr = new char[10] ;
    > }
    >
    > ~test()
    > {
    > delete cPtr ;
    > }
    > } ;
    >
    >
    > int main()
    > {
    > std::vector< test*> vecTest ;
    >
    > test* testPtr = new test() ;
    >
    > vecTest.push_back( testPtr ) ;
    >
    > delete testPtr ;
    >
    > vecTest.clear() ;
    > }


    Nope. As pointers have their own copy constructor, you can use them in
    STL containers freely.

    Regards,
    Stuart
     
    Stuart Redmann, Jan 11, 2007
    #2
    1. Advertising

  3. peter koch Guest

    skrev:
    > Will the following program cause any problem, because of the missing
    > explicit copy constructor for the 'test' class?


    Yes. You will have double deletes. Depending on your real needs, you
    should use std::vector or std::string instead of the lowlevel pointer.
    In fact, operator new[] should almost never be used. Prefer std::vector
    (or in rare situations raw operator new)

    /Peter
    >
    > #include <vector>
    > #include <iostream>
    >
    > class test
    > {
    > char* cPtr ;
    >
    > public:
    >
    > test()
    > {
    > cPtr = new char[10] ;
    > }
    >
    > ~test()
    > {
    > delete cPtr ;
    > }
    > } ;
    >
    >
    > int main()
    > {
    > std::vector< test*> vecTest ;
    >
    > test* testPtr = new test() ;
    >
    > vecTest.push_back( testPtr ) ;
    >
    > delete testPtr ;
    >
    > vecTest.clear() ;
    > }
     
    peter koch, Jan 11, 2007
    #3
  4. Guest

    peter koch wrote:
    > skrev:
    > > Will the following program cause any problem, because of the missing
    > > explicit copy constructor for the 'test' class?

    >
    > Yes. You will have double deletes.

    You are right, in general (Every class having a pointer member should
    have an explicit constructor defined correctly).
    But, could you comment whether it will cause problem for the code that
    I have given within main()?

    > Depending on your real needs, you
    > should use std::vector or std::string instead of the lowlevel pointer.
    > In fact, operator new[] should almost never be used. Prefer std::vector
    > (or in rare situations raw operator new)
     
    , Jan 11, 2007
    #4
  5. dasjotre Guest

    wrote:
    > Will the following program cause any problem, because of the missing
    > explicit copy constructor for the 'test' class?


    I don't think that the copy constructor is generated in this case
    since it is not used.

    > But, could you comment whether it will cause problem for the code that
    > I have given within main()?


    since only the pointer is copied and not the object it poins to the
    answer is no.

    ( delete cPtr should be delete [] cPtr )
     
    dasjotre, Jan 11, 2007
    #5
  6. peter koch Guest

    skrev:
    > peter koch wrote:
    > > skrev:
    > > > Will the following program cause any problem, because of the missing
    > > > explicit copy constructor for the 'test' class?

    > >
    > > Yes. You will have double deletes.

    > You are right, in general (Every class having a pointer member should
    > have an explicit constructor defined correctly).
    > But, could you comment whether it will cause problem for the code that
    > I have given within main()?


    It is not. But this is no excuse for disabling copy-construction (and
    assignment).

    /Peter
     
    peter koch, Jan 11, 2007
    #6
  7. Stuart Redmann wrote:
    > wrote:
    >> Will the following program cause any problem, because of the missing
    >> explicit copy constructor for the 'test' class?
    >>
    >> #include <vector>
    >> #include <iostream>
    >>
    >> class test
    >> {
    >> char* cPtr ;
    >>
    >> public:
    >>
    >> test()
    >> {
    >> cPtr = new char[10] ;
    >> }
    >>
    >> ~test()
    >> {
    >> delete cPtr ;
    >> }
    >> } ;
    >>
    >>
    >> int main()
    >> {
    >> std::vector< test*> vecTest ;
    >>
    >> test* testPtr = new test() ;
    >>
    >> vecTest.push_back( testPtr ) ;
    >>
    >> delete testPtr ;
    >>
    >> vecTest.clear() ;
    >> }

    >
    > Nope. As pointers have their own copy constructor, you can use them in
    > STL containers freely.


    Woah there! That's horrible advice. Without a copy constructor, using
    such an object in an STL container will invariably lead to
    double-deletes (i.e. undefined behavior).

    Remember the rule of three: Generally, if a class requires any of the
    following three to be implemented then it requires that *all* of the
    three be implemented:

    destructor
    assignment operator
    copy constructor

    --
    Clark S. Cox III
     
    Clark S. Cox III, Jan 11, 2007
    #7
  8. dasjotre wrote:
    > wrote:
    >> Will the following program cause any problem, because of the missing
    >> explicit copy constructor for the 'test' class?

    >
    > I don't think that the copy constructor is generated in this case
    > since it is not used.


    Conceptually, the copy constructor is always generated unless you
    provide one. Whether that has an impact on the final output of the
    compiler when it isn't called is platform dependent.

    > > But, could you comment whether it will cause problem for the code that
    > > I have given within main()?

    >
    > since only the pointer is copied and not the object it poins to the
    > answer is no.
    >
    > ( delete cPtr should be delete [] cPtr )
    >



    --
    Clark S. Cox III
     
    Clark S. Cox III, Jan 11, 2007
    #8
  9. Clark S. Cox III wrote:

    > Woah there! That's horrible advice. Without a copy constructor, using
    > such an object in an STL container will invariably lead to
    > double-deletes (i.e. undefined behavior).


    The point is here that not the object is used in the container. A
    pointer to the object is. The example as shown has no problems (apart
    from the "delete" instead of "delete[]"). Even if the object is not
    copy-able, you can still use pointers in a container.

    What I would do is to make the class explicitly non-copyable and
    non-assignable, so the compiler can report any misuse.
     
    Eberhard Schefold, Jan 11, 2007
    #9
  10. Pete Becker Guest

    Clark S. Cox III wrote:
    > Stuart Redmann wrote:
    >> As pointers have their own copy constructor, you can use them in
    >> STL containers freely.

    >
    > Woah there! That's horrible advice. Without a copy constructor, using
    > such an object in an STL container will invariably lead to
    > double-deletes (i.e. undefined behavior).
    >


    Whoa, again! In the specific context of the original example, there is
    no problem with double deletes. Pointers do, in fact, have valid copy
    semantics. There is, as you suggest, a possible issue of keeping track
    of ownership, but there's nothing wrong with the original code. It
    correctly deletes the one object that it creates.

    If you want a container to also manage lifetimes, then you've got a
    significant design problem: you also have to make sure that every other
    piece of code is clear on ownership. But there are situations where it's
    appropriate for a container to manage pointers but not worry about
    lifetimes, such as maintaining a list of currently active objects from a
    set of statically allocated ones.

    --

    -- Pete
    Roundhouse Consulting, Ltd. (www.versatilecoding.com)
    Author of "The Standard C++ Library Extensions: a Tutorial and
    Reference." (www.petebecker.com/tr1book)
     
    Pete Becker, Jan 11, 2007
    #10
  11. Pete Becker Guest

    peter koch wrote:
    > skrev:
    >> Will the following program cause any problem, because of the missing
    >> explicit copy constructor for the 'test' class?

    >
    > Yes. You will have double deletes.


    No, there are no double deletes in the posted code.

    > Depending on your real needs, you
    > should use std::vector or std::string instead of the lowlevel pointer.
    > In fact, operator new[] should almost never be used. Prefer std::vector
    > (or in rare situations raw operator new)
    >
    > /Peter
    >> #include <vector>
    >> #include <iostream>
    >>
    >> class test
    >> {
    >> char* cPtr ;
    >>
    >> public:
    >>
    >> test()
    >> {
    >> cPtr = new char[10] ;
    >> }
    >>
    >> ~test()
    >> {
    >> delete cPtr ;
    >> }
    >> } ;
    >>
    >>
    >> int main()
    >> {
    >> std::vector< test*> vecTest ;
    >>


    Object allocated here, never copied:

    >> test* testPtr = new test() ;
    >>
    >> vecTest.push_back( testPtr ) ;
    >>


    Object deleted here, exactly once.

    >> delete testPtr ;
    >>
    >> vecTest.clear() ;
    >> }

    >



    --

    -- Pete
    Roundhouse Consulting, Ltd. (www.versatilecoding.com)
    Author of "The Standard C++ Library Extensions: a Tutorial and
    Reference." (www.petebecker.com/tr1book)
     
    Pete Becker, Jan 11, 2007
    #11
  12. Pete Becker wrote:
    > Clark S. Cox III wrote:
    > > Stuart Redmann wrote:
    > > > As pointers have their own copy constructor, you can use them in
    > > > STL containers freely.

    > >
    > > Woah there! That's horrible advice. Without a copy constructor, using
    > > such an object in an STL container will invariably lead to
    > > double-deletes (i.e. undefined behavior).
    > >

    >
    > Whoa, again! In the specific context of the original example, there is
    > no problem with double deletes. Pointers do, in fact, have valid copy
    > semantics.


    Indeed, I see that now (i.e. that the OP was creating a vector of
    *pointers* to test).

    --
    Clark S. Cox III
     
    Clark S. Cox III, Jan 11, 2007
    #12
  13. Jim Langston Guest

    <> wrote in message
    news:...
    > Will the following program cause any problem, because of the missing
    > explicit copy constructor for the 'test' class?
    >
    > #include <vector>
    > #include <iostream>
    >
    > class test
    > {
    > char* cPtr ;
    >
    > public:
    >
    > test()
    > {
    > cPtr = new char[10] ;
    > }
    >
    > ~test()
    > {
    > delete cPtr ;
    > }
    > } ;
    >
    >
    > int main()
    > {
    > std::vector< test*> vecTest ;
    >
    > test* testPtr = new test() ;
    >
    > vecTest.push_back( testPtr ) ;
    >
    > delete testPtr ;
    >
    > vecTest.clear() ;
    > }


    As used, there won't be a problem. But, you should either make a non public
    copy and assignment operator, or make them. The reason is if you do try to
    copy this class you'll get a double delete. Making a non public copy and
    assignement operator means you can't accidently copy the class.
     
    Jim Langston, Jan 11, 2007
    #13
  14. Pete Becker Guest

    Clark S. Cox III wrote:
    > Pete Becker wrote:
    >> Clark S. Cox III wrote:
    >>> Stuart Redmann wrote:
    >>>> As pointers have their own copy constructor, you can use them in
    >>>> STL containers freely.
    >>> Woah there! That's horrible advice. Without a copy constructor, using
    >>> such an object in an STL container will invariably lead to
    >>> double-deletes (i.e. undefined behavior).
    >>>

    >> Whoa, again! In the specific context of the original example, there is
    >> no problem with double deletes. Pointers do, in fact, have valid copy
    >> semantics.

    >
    > Indeed, I see that now (i.e. that the OP was creating a vector of
    > *pointers* to test).
    >


    Yup. Looking at how to use non-copyable objects in containers, I suspect.

    --

    -- Pete
    Roundhouse Consulting, Ltd. (www.versatilecoding.com)
    Author of "The Standard C++ Library Extensions: a Tutorial and
    Reference." (www.petebecker.com/tr1book)
     
    Pete Becker, Jan 11, 2007
    #14
  15. peter koch Guest

    Pete Becker skrev:
    > peter koch wrote:
    > > skrev:
    > >> Will the following program cause any problem, because of the missing
    > >> explicit copy constructor for the 'test' class?

    > >
    > > Yes. You will have double deletes.

    >
    > No, there are no double deletes in the posted code.
    >

    [snip]

    You are right - I only skimmed "main" and failed to notice that it was
    a vector of pointers. Still, there's no excuse for not hiding operator=
    and the copy constructor.

    /Peter
     
    peter koch, Jan 11, 2007
    #15
  16. Pete Becker Guest

    peter koch wrote:
    > Pete Becker skrev:
    >> peter koch wrote:
    >>> skrev:
    >>>> Will the following program cause any problem, because of the missing
    >>>> explicit copy constructor for the 'test' class?
    >>> Yes. You will have double deletes.

    >> No, there are no double deletes in the posted code.
    >>

    > [snip]
    >
    > You are right - I only skimmed "main" and failed to notice that it was
    > a vector of pointers. Still, there's no excuse for not hiding operator=
    > and the copy constructor.
    >


    Sure there is: it's an experiment, not production code.

    --

    -- Pete
    Roundhouse Consulting, Ltd. (www.versatilecoding.com)
    Author of "The Standard C++ Library Extensions: a Tutorial and
    Reference." (www.petebecker.com/tr1book)
     
    Pete Becker, Jan 11, 2007
    #16
  17. Grizlyk Guest

    Pete Becker wrote:
    >
    > Yup. Looking at how to use non-copyable objects in containers, I suspect.


    But dangerous usage

    > test() { cPtr = new char[10] ; }

    test():cPtr(new char[10]) { }

    > ~test(){ delete cPtr ; }

    ~test(){ delete[] cPtr ; }

    "" must at least define private copy&assign
    private:
    test(const test&):cPtr(0) { abort(); }
    void operator= (const test&){ abort(); }

    and he does not call "delete testPtr;" befor "vecTest.clear() ;"
     
    Grizlyk, Jan 14, 2007
    #17
  18. Pete Becker Guest

    Grizlyk wrote:
    > Pete Becker wrote:
    >> Yup. Looking at how to use non-copyable objects in containers, I suspect.

    >
    > But dangerous usage
    >
    >> test() { cPtr = new char[10] ; }

    > test():cPtr(new char[10]) { }
    >
    >> ~test(){ delete cPtr ; }

    > ~test(){ delete[] cPtr ; }
    >
    > "" must at least define private copy&assign
    > private:
    > test(const test&):cPtr(0) { abort(); }
    > void operator= (const test&){ abort(); }
    >
    > and he does not call "delete testPtr;" befor "vecTest.clear() ;"
    >


    No, there's nothing dangerous in the code as written. But I'm sure he's
    grateful for all the advice about how code that's supposed to do
    something different should be written.

    --

    -- Pete
    Roundhouse Consulting, Ltd. (www.versatilecoding.com)
    Author of "The Standard C++ Library Extensions: a Tutorial and
    Reference." (www.petebecker.com/tr1book)
     
    Pete Becker, Jan 14, 2007
    #18
    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. Aire
    Replies:
    3
    Views:
    476
    Mike Wahler
    Jan 25, 2004
  2. highli
    Replies:
    17
    Views:
    651
    Alf P. Steinbach
    Jul 25, 2004
  3. ali
    Replies:
    4
    Views:
    592
    David Harmon
    Mar 5, 2007
  4. Generic Usenet Account
    Replies:
    10
    Views:
    2,292
  5. cinsk
    Replies:
    35
    Views:
    2,662
    James Kanze
    Oct 11, 2010
Loading...

Share This Page