Consider the following code:
class Foo
{
public:
//class-specific
Foo operator+(Foo& rhs)
{
return Foo(); //Just return a temporary
}
void* operator new(size_t sd)
{
return malloc(sd);
}
};
//global
Foo operator+(Foo& lhs, Foo& rhs)
{
return Foo();
}
void* operator new(size_t sd)
{
return malloc(sd);
}
This code will not compile, stating the call is ambiguous because it matches two operators:
Foo a, b;
a + b;
But this one with the new operator compiles just fine, and will call the class-specific one.
Foo* a = new Foo();
Why doesn't it result in a compile error? Does the compiler treat the new operator differently? (Any citation to the standard would be appreciated.)
How does the compiler differentiates the class-specific function and a global function? To map the function call with the corresponding function definition, the compiler performs the process of name-lookup. This process yields some set of functions that have the same name and they are called candidate functions.
The new operator is an operator which denotes a request for memory allocation on the Heap. If sufficient memory is available, new operator initializes the memory and returns the address of the newly allocated and initialized memory to the pointer variable.
The operator new (or better the void* operator new(size_t) variant) just allocate memory, but does not do any object construction. The new keyword calls the operator new function, but then calls the object constructor.
Use of the new operator signifies a request for the memory allocation on the heap. If the sufficient memory is available, it initializes the memory and returns its address to the pointer variable. The new operator should only be used if the data object should remain in memory until delete is called.
Why doesn't it result in a compile error? Does the compiler treat the new operator differently? (Any citation to the standard would be appreciated)
Regarding the precedence between global new
and class specific new
, the reference says this:
As described in allocation function, the C++ program may provide global and class-specific replacements for these functions. If the new-expression begins with the optional :: operator, as in ::new T or ::new T[n], class-specific replacements will be ignored (the function is looked up in global scope). Otherwise, if T is a class type, lookup begins in the class scope of T.
So class specific new
has priority.
Regarding the overload of +
, you can either have the member overload or the global overload (usually as a friend
of the class) but not both because of the ambiguity it produces.
The class' operator new
is always preferred if defined:
[expr.new]/9
If the new-expression begins with a unary
::
operator, the allocation function's name is looked up in the global scope. Otherwise, if the allocated type is a class typeT
or array thereof, the allocation function's name is looked up in the scope ofT
. If this lookup fails to find the name, or if the allocated type is not a class type, the allocation function's name is looked up in the global scope.
It can be tricky to read: if the new-expression does not begins with ::
and the allocated type is a class type, then new
is looked up in the class' scope.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With