Obj* ptr = new Obj(X)

Discussion in 'C++' started by Phil Endecott, Jun 3, 2005.

  1. Dear All,

    I'm experimenting with a class that allocates itself using a nonstandard
    allocator:

    class Obj {
    public:

    static void* operator new (size_t sz) {
    return my_allocate(sz);
    }
    static void* operator new[] (size_t sz) {
    return my_allocate(sz);
    }
    static void operator delete (void* p, size_t sz) {
    my_deallocate(p, sz);
    }
    static void operator delete[] (void* p, size_t sz) {
    my_deallocate(p, sz);
    }
    ... etc ...
    };

    This works fine for simple cases, but I am not sure how to deal with
    this use of new:

    Obj* ptr = new Obj(X)

    I believe that this should allocate a new Obj and invoke its
    copy-constructor to initialise it with a copy of X. I think that, in
    order to support this, I need to implement

    static void* operator new (size_t sz, const Obj& o)

    Is this right? So, what should this function do? Maybe

    obj* p = my_allocate(sz);
    *p = o;
    return p;

    But this seems all wrong. Surely the purpose of operator new is to
    allocate the memory, with construction happening later. And what about
    subclasses of Obj?

    I think I am missing something basic here - can someone help me out?

    Cheers, --Phil.
     
    Phil Endecott, Jun 3, 2005
    #1
    1. Advertising

  2. Phil Endecott

    John Carson Guest

    "Phil Endecott" <> wrote in message
    news:zU_ne.2410$
    > Dear All,
    >
    > I'm experimenting with a class that allocates itself using a
    > nonstandard allocator:


    [snip]
    >
    > This works fine for simple cases, but I am not sure how to deal with
    > this use of new:
    >
    > Obj* ptr = new Obj(X)
    >
    > I believe that this should allocate a new Obj and invoke its
    > copy-constructor to initialise it with a copy of X. I think that, in
    > order to support this, I need to implement
    >
    > static void* operator new (size_t sz, const Obj& o)
    >
    > Is this right?


    No.

    > So, what should this function do? Maybe
    >
    > obj* p = my_allocate(sz);
    > *p = o;
    > return p;
    >
    > But this seems all wrong. Surely the purpose of operator new is to
    > allocate the memory, with construction happening later. And what about
    > subclasses of Obj?
    >
    > I think I am missing something basic here - can someone help me out?


    Any user-defined operator new is responsible solely for memory allocation.
    Constructor calls will be handled by the compiler, just as if you were using
    the standard operator new.

    --
    John Carson
     
    John Carson, Jun 3, 2005
    #2
    1. Advertising

  3. John Carson wrote:
    > Phil Endecott wrote
    >> I am not sure how to deal with
    >> this use of new:
    >>
    >> Obj* ptr = new Obj(X)
    >>
    >> I think that, in
    >> order to support this, I need to implement
    >>
    >> static void* operator new (size_t sz, const Obj& o)
    >>
    >> Is this right?


    > No.
    > Any user-defined operator new is responsible solely for memory allocation.
    > Constructor calls will be handled by the compiler, just as if you were
    > using the standard operator new.


    Thanks John. That makes sense.

    I found myself thinking the wrong way because of an error message:

    /usr/include/c++/3.3/bits/stl_construct.h:78: error: no matching
    function for
    call to `shm_vec_char::eek:perator new(unsigned int, void*&)'
    .../apachemod/shm_alloc.h:278: error: candidates are: static void*
    Shm::Obj::eek:perator new(unsigned int)

    I am trying to store these things in a std::vector, and there is more
    going on than I have explained. I'll post again if I can come up with a
    sufficiently simple example.

    --Phil.
     
    Phil Endecott, Jun 3, 2005
    #3
  4. Phil Endecott

    Mark P Guest

    Phil Endecott wrote:
    > John Carson wrote:
    >
    >> Phil Endecott wrote
    >>
    >>> I am not sure how to deal with
    >>> this use of new:
    >>>
    >>> Obj* ptr = new Obj(X)
    >>>
    >>> I think that, in
    >>> order to support this, I need to implement
    >>>
    >>> static void* operator new (size_t sz, const Obj& o)
    >>>
    >>> Is this right?

    >
    >
    >> No.
    >> Any user-defined operator new is responsible solely for memory
    >> allocation.
    >> Constructor calls will be handled by the compiler, just as if you were
    >> using the standard operator new.

    >
    >
    > Thanks John. That makes sense.
    >
    > I found myself thinking the wrong way because of an error message:
    >
    > /usr/include/c++/3.3/bits/stl_construct.h:78: error: no matching
    > function for
    > call to `shm_vec_char::eek:perator new(unsigned int, void*&)'
    > ../apachemod/shm_alloc.h:278: error: candidates are: static void*
    > Shm::Obj::eek:perator new(unsigned int)
    >
    > I am trying to store these things in a std::vector, and there is more
    > going on than I have explained. I'll post again if I can come up with a
    > sufficiently simple example.
    >
    > --Phil.


    I believe it's more complicated if you want to store your objects in an
    STL class.

    If you just store pointers nothing really special happens, but since STL
    classes own their objects and allocate memory for them via their own
    allocator objects, it's unlikely that your operator new will ever be
    called.

    Instead I think STL classes will invoke placement new after allocating
    the memory themselves. This is in fact what your error message
    indicates-- notice the function it's looking for looks like: operator
    new(unsigned int, void*). The unsigned int is size_t on your system,
    and the void* is the location for the new object.

    By defining your own operator new you hide the global placement new.
    Try adding:

    void* operator new(size_t size, void* loc) {return ::eek:perator
    new(size,loc);}

    to your class definition, which will restore access to global placement new.

    Hope that helps,
    Mark
     
    Mark P, Jun 3, 2005
    #4
  5. Mark P wrote:
    > By defining your own operator new you hide the global placement new. Try
    > adding:
    >
    > void* operator new(size_t size, void* loc) {return ::eek:perator
    > new(size,loc);}


    Thanks! I didn't know it would be hidden.
    I presume I also need a version for new[] :

    void* operator new[] (size_t size, void* loc) {
    return ::eek:perator new[](size,loc);
    }

    --Phil.
     
    Phil Endecott, Jun 3, 2005
    #5
  6. Phil Endecott

    Mark P Guest

    Phil Endecott wrote:
    > Mark P wrote:
    >
    >> By defining your own operator new you hide the global placement new.
    >> Try adding:
    >>
    >> void* operator new(size_t size, void* loc) {return ::eek:perator
    >> new(size,loc);}

    >
    >
    > Thanks! I didn't know it would be hidden.
    > I presume I also need a version for new[] :
    >
    > void* operator new[] (size_t size, void* loc) {
    > return ::eek:perator new[](size,loc);
    > }
    >
    > --Phil.


    I'm not an expert but I imagine it can't hurt. Not sure how often
    placement new[] is actually used though. I don't think I've ever
    encountered an STL allocator which attempted to use this.
     
    Mark P, Jun 3, 2005
    #6
    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. Sid
    Replies:
    5
    Views:
    1,086
  2. Heiko Vogel
    Replies:
    3
    Views:
    572
    Method Man
    Sep 14, 2004
  3. franco ziade

    const ptr to const ptr ?

    franco ziade, Feb 17, 2005, in forum: C Programming
    Replies:
    3
    Views:
    406
    franco ziade
    Feb 17, 2005
  4. G Fernandes
    Replies:
    9
    Views:
    608
    DHOLLINGSWORTH2
    Feb 27, 2005
  5. Jason

    difference between *ptr++ and ++*ptr ?

    Jason, May 15, 2005, in forum: C Programming
    Replies:
    19
    Views:
    6,582
    Chris Torek
    May 19, 2005
Loading...

Share This Page