LINUX.ORG.RU

C++, private деструктор мешает сделать new T[N];, но не мешает new T; Почему?


0

1
#include <iostream>

class XX
{
public:
    XX() {std::cout<<"C XX\n";}
private:
    ~XX() {std::cout<<"~ XX\n";}
};

int main() {
    XX *xx=new XX[10];   // compile error (1)
    XX x_auto;           // compile error (2)

    XX *xx=new XX;       // ok (3)
    delete xx;           // compile error (4)

    return 0;
}

Есть гипотезы.

(1) - ошибка, ибо в случае исключения в конструкторе XX() при конструировании 5-го элемента, компилятор должен будет вызвать (сгенерить код вызова) деструктора ~XX() для предыдущих 4 успешно сконструированных объектов и не сможет этого сделать по причине приватности сего деструктора. Вероятность сего исключения невозможно понять на этапе компиляции, поэтому такое запрещено.

(2) - ошибка, ибо объект x_auto - автоматический (на стеке), что означает неизбежность вызова его деструктора, что невозможно из-за приватности сего деструктора.

(3) - ОК, т.к. возможное исключение из конструктора не сопровождается вызовом никаких деструкторов, а программист может деструктор вообще не вызывать, ибо объект не автоматический.

(4) - ошибка, не могу вызвать деструктор - его нет (приватный, наружу не торчит).

Ответ на: комментарий от kiverattes

А что изменилось? Та же декларация функции xx2(void), возвращающей XX.

А, да, это проворонил. Смотрел только не new, хотя дисскусия была про другое.

KennyMinigun ★★★★★
()
Ответ на: комментарий от KennyMinigun

Причина в том, что есть 2 разные ситуации:

1) «Пойманное исключение»
2) «Не пойманное исключение»

Для компилятора это два разных сценария. Во втором сценарии он просто рубает с плеча, а в первом происходят умные вещи, такие как раскрутка стека и аккуратное удаление половины созданных элементов обломавшегося массива.

kiverattes ★☆
() автор топика
Последнее исправление: kiverattes (всего исправлений: 1)
Ответ на: комментарий от kiverattes

Бтв, декларации функций вида type foo(void); формально запрещены стандартом, но ради совместимости с сишными хедерами в gcc встроен специальный костыль (который, печаль, не работает со всякими тайпдефами).

ilammy ★★★
()

Если сделать ~XX() public, то видно что он все равно не вызывается и вроде бы на фиг не нужен, но для массива XX *xx=new XX[10] используются _vec_new и _vec_delete из библиотеки С++, а у них аргументы адреса конструкторов и деструкторов, поэтому компилятор и требует public ~XX().

ilovewindows ★★★★★
()

Так что тебя смущает-то?

И да, ты как в прошлом веке живешь. unique_ptr и все такое где?

anonymous
()
Ответ на: комментарий от next_time

Да это для затравки. Из своего опыта раз пришлось устраивать нехилых масштабов рефакторинг из-за кучи статических глобальных сущностей. А ведь это по сути те же синглтоны.

nanoolinux ★★★★
()
Ответ на: комментарий от ilovewindows

Познавательно, спасибо.

Вроде бы это и есть ответ на вопрос ТСа.

Adonai ★★★
()
Ответ на: комментарий от Stahl

Не могу навскидку придумать зачем бы это могло понадобиться.

Чтобы нельзя было создавать объекты на стеке

Boy_from_Jungle ★★★★
()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.