views:

110

answers:

2

Hi,

At the end of Item 52 (Customising new and delete) in Myer's Effective C++ he discusses how to avoid hiding normal new and delete versions when implementing custom version as follows:

If you declare any operator news in a class, you'll hide all these standard forms. Unless you mean to prevent class clients from using these forms, be sure to make them available in addition to any custom operator new forms you create. For each operator new you make available, of course, be sure to offer the corresponding operator delete, too. If you want these functions to behave in the usual way, just have your class-specific versions call the global versions.

An easy way to do this is to create a base class containing all the normal forms of new and delete:

class StandardNewDeleteForms {

public:

  // normal new/delete

  static void* operator new(std::size_t size) throw(std::bad_alloc)

  { return ::operator new(size); }

  static void operator delete(void
*pMemory) throw()

  { ::operator delete(pMemory); }



  // placement new/delete

  static void* operator new(std::size_t size, void *ptr) throw()

  { return ::operator new(size, ptr); }

  static void operator delete(void
*pMemory, void *ptr) throw()

  { return ::operator delete(pMemory, ptr); }



  // nothrow new/delete

  static void* operator new(std::size_t size, const std::nothrow_t& nt) throw()

  { return ::operator new(size, nt); }

  static void operator delete(void
*pMemory, const std::nothrow_t&) throw()

  { ::operator delete(pMemory); }

};

Clients who want to augment the standard forms with custom forms can then just use inheritance and using declarations (see Item 33) to get the standard forms:

class Widget: public StandardNewDeleteForms {           // inherit std forms

public:

   using StandardNewDeleteForms::operator new;  // make those

   using StandardNewDeleteForms::operator delete;       // forms visible



   static void* operator new(std::size_t size,          // add a custom

                             std::ostream& logStream)   // placement new

     throw(std::bad_alloc);



   static void operator delete(void
*pMemory,           // add the corres-

                               std::ostream& logStream) // ponding place-

    throw();                                            // ment delete

  ...

};

Why go to the bother of creating the class StandardNewDeleteForms, inheriting from it and then in the derived class saying:

using StandardNewDeleteForms::operator new;
using StandardNewDeleteForms::operator delete;

Could you not forgo the base class altogether and simply write in the Widget class:

using ::operator new;
using ::operator delete;

to achieve the same thing?

+1  A: 

That would effectively be a no-op using. He's simply showing an implementation of the base class new/delete that would duplicate the normal behavior.

Usually if you're creating a custom new and delete you would have changed behavior in that base class and the using ::operator new; would no longer be equivalent. He didn't do that in his example so it's slightly less clear what's happening.

Mark B
Hi Mark, thanks for your answer although I didn't quite follow your points completely. You said: "That would effectively be a no-op using.", I didn't quite understand how you meant it would be effectively a no-op so I tried compiling what I proposed (using ::operator new;) and I get the error - 'operator new' : symbol cannot be used in a member using-declaration'So I guess that construct isn't allowed by the language specification at all, i.e. a using declaration for a class member can only refer to a member inherited from a base class. Is my thinking correct here?
Czarak
A: 

First, it's not allowed to do using ::operator new; as it's not a member of parent class.

Second, the global new is'nt useful to overload because most of the time : 1. you'll use libraries that use or not this operator, making a mess; 2. you might want to use different new/delete code for different type of objects;

The idea behind this item is that you can change the new/delete behavior of classes that inherit the parent class, allowing changing allocation strategy for a whole group of classes.

Klaim
Hi, I don't really understand most of your answer but in particular the first line? Maybe you can elaborate a bit?
Czarak