I am having hard time digesting this syntax:
void* operator new[](std::size_t, const std::nothrow_t&) throw();
while this is still understood:
void* operator new (std::size_t size, const std::nothrow_t& nothrow_constant) throw();
Question:
-
I thought
newand subscript[]are different operators. how can we combine two operators to overload in one definition? -
Also the
nowthrow. The following call doesnt make sense to me ( with respect to the signature of the function ).int * p2 = new (nothrow) int;
If anyone can give reference to related topics from bjarne stroustrup’s book that would be great, not a hard requirement though.
UPDATE: Please try to answer both questions 🙂
The first two are the signatures of the global new operators. For what (little) it’s worth,
operator newis used to allocate space for a new expression likex = new T;, whileoperator new[]is used to allocate space for a new expression likex = new T[count];. The “little” that it’s worth is for a fairly simple reason: you should never usenew T[count], so how it works is almost purely a historical curiosity.You can overload
::operator newand/or::operator new[]to provide your own heap allocation if you want to. There’s no difference between the two as far as basic requirements go — they both just allocate and return a pointer to the amount of memory requested.As far as
nothrowgoes, the size that gets passed tooperator newis always computed by the compiler based on the size of the object and in the case of an array new the count you give. Therefore, the parameter you specify in the new expression turns into the second parameter that’s passed tooperator new.To emphasize a point I may not have made quite clearly enough above:
operator new(andoperator new[]) are used by, but separate from new expressions (what you have in your code when you say something likex = new T;).operator newandoperator new[]are pretty much likemalloc— they just allocate “raw” memory. A new expression1 uses one of those to allocate raw memory, then invokes the constructor to allocate an object (or more than one, in the case ofnew T[count];) in that memory. The two are obviously related, but equally obviously not really the same.One other minor point: it’s also possible to have an
operator new(oroperator new[]as a class member. This allows you to allocate memory differently for that class than for others that use the global heap. This tends to be most common with small objects that you expect to allocate in large numbers. For these, the global heap often has quite a lot of overhead that you’d prefer to avoid.Finally, when/if you want to allocate raw memory, you can also invoke
operator newdirectly, as invoid *a = ::operator new(1234);. About the only place this is common is if you decide to implement some sort of collection class on your own (e.g., if you want a circular buffer).