Подтвердить что ты не робот

Почему исходный код sgi stl использует двойную двоеточие перед новой функцией оператора?

Я читаю исходный код стандартной библиотеки шаблонов SGI. Я считаю, что функция operator new всегда имеет перед собой двойную двоеточие. Вот так:

T* tmp = (T*)(::operator new((size_t)(size * sizeof(T))));

operator new можно напрямую вызвать без добавления поля ::, то почему stl-кодеры пишут таким образом? Какая ловушка или ситуация могут возникнуть, если мы не используем :: перед ними.

4b9b3361

Ответ 1

Вы можете перегрузить оператор new для класса, а его префикс "::" вызовет глобальный "по умолчанию" оператор new вместо возможной перегрузки. Например:

#include <iostream>

class Foo
{
public:
  Foo() { std::cout << "Foo::Foo()" << std::endl; }

  void * operator new(size_t )
  { 
    std::cout << "Foo::operator new()" << std::endl; 
    return static_cast<Foo *>(malloc(sizeof(Foo)));
  }
};


int main()
{
  Foo foo;
  std::cout << "----------------------" << std::endl;
  Foo * p = new Foo;
  std::cout << "----------------------" << std::endl;
  Foo * q = ::new Foo;
}

напечатает

Foo::Foo()
----------------------
Foo::operator new()
Foo::Foo()
----------------------
Foo::Foo()

Изменить: код, который был отключен, действительно не о новом операторе, который определен в области класса. Лучшим примером может быть следующее:

#include <iostream>

namespace quux {

void * operator new(size_t s)
{
  std::cout << "quux::operator new" << std::endl;
  return malloc(s);
}

void foo()
{
  std::cout << "quux::foo()" << std::endl;
  int * p = static_cast<int*>(operator new(sizeof(int)));
}

void bar()
{
  std::cout << "quux::bar()" << std::endl;
  int * p = static_cast<int*>(::operator new(sizeof(int)));
}

} // namespace quux


int main()
{
  quux::foo();
  quux::bar();
}

который печатает

quux::foo()
quux::operator new
quux::bar()

Ответ 2

::operator new в С++ - это глобальный распределитель памяти, который вызывается каждый раз, когда требуется определенное количество байтов для одного объекта. Обратите внимание, что возвращаемое значение равно void * и что ::operator new(size_t) имеет дело с необработанными байтами, а не с объектами.

В основном это С++-аналог malloc с просто смешным именем.

Вместо этого используется выделенный глобальный распределитель ::operator new[](size_t sz) для выделения памяти для массивов объектов.

Эти два оператора, их аналоги ::operator delete и ::operator delete[], а также nothrow версия распределители используются для всех потребностей памяти во время выполнения С++.

Они могут быть реализованы с точки зрения вызовов malloc/free или нет. Что гарантирует, что malloc и free не использовать их (таким образом, вы можете вызвать malloc и free если вы хотите переопределять эти функции без риска бесконечной рекурсии).

Ответ 3

Двойная двоеточие используется для предотвращения вызова T:: operator new() (если определены).

Ответ 4

Чтобы вызвать operator new из глобального пространства имен, если пользователь (или кто-то) решил использовать оператор new.