оператор new для массива класса без конструктора по умолчанию - PullRequest
2 голосов
/ 26 марта 2010

Для класса без конструктора по умолчанию оператор new и размещение new могут использоваться для объявления массива такого класса.

Когда я читал код в More Effective C ++, я обнаружил код, как показано ниже (я изменил некоторую часть) .....

У меня вопрос: зачем [] после оператора новый нужен?

Я тестирую это без него, оно все еще работает. Может ли кто-нибудь объяснить это?

class A {
    public:
    int i;

    A(int i):i(i) {}
};

int main()
{
      void *rawMemory = operator new[] (10 * sizeof(A));   // Why [] needed here?
      A *p = static_cast<A*>(rawMemory);

      for(int i = 0 ; i < 10 ; i++ ) {

            new(&p[i])A(i); 

      }

      for(int i = 0 ; i < 10 ; i++ ) {

            cout<<p[i].i<<endl;

      }

      for(int i = 0 ; i < 10 ; i++ ) {

            p[i].~A();

      }

    return 0;
}

Ответы [ 4 ]

2 голосов
/ 26 марта 2010

Я удивлен, что Effective C ++ посоветовал бы вам использовать что-то столь же хакерское, как void*.

new[] делает очень специфическую вещь: он выделяет массив с динамическим размером . Массив, выделенный вместе с ним, должен быть передан в delete[]. delete[] затем читает скрытое число, чтобы найти, сколько элементов в массиве, и уничтожает объекты , как вы сделали с p[i].~A();.

Однако это использование несовместимо с этим. Массив имеет статический размер, и невозможно получить это скрытое число или уничтожение в динамическом размере без правильного использования new[] (без operator), в свою очередь требующего конструктора по умолчанию. Подлинная слабость C ++.

Если вы позвоните delete[] в конце main, как и предполагали другие, ваш код может дать сбой. Вместо этого вам нужно использовать operator delete[], который выглядит как опечатка и является просто авария в ожидании.

Используйте не массив operator new и operator delete и достаточно комментариев, если вы должны использовать этот трюк. Но я не считаю это особенно эффективным C ++.

2 голосов
/ 26 марта 2010

Это не нужно. Единственная разница между оператором new и оператором new [] заключается в том, что первое вызывается с использованием ключевого слова new, а другое - с помощью ключевого слова new []. Оба выделяют сырую память.

Просто убедитесь, что когда вы, наконец, освободите память (ваш код здесь просто просачивается), вы вызываете delete или delete [], которая соответствует новой или новой [].

1 голос
/ 26 марта 2010

Строго не нужно в этом случае. Они оба будут выделять одинаковый объем памяти, но для одного потребуется delete, а для другого потребуется delete[] в конце. Использование new[] делает ваше намерение более ясным, поэтому оно используется здесь.

0 голосов
/ 26 марта 2010

Это на самом деле не нужно - это просто дает вам возможность выделить память для массивов отдельно от памяти для отдельных объектов, если вы решите это сделать.

...