NULL в деструкторе класса

Возможный дубликат:
Стоит ли устанавливать указатели в NULL в деструкторе?

Разве бессмысленно устанавливать указатель (который выделяет память кучи) на NULL в деструкторе?

class SampleClass
{
    public:
        SampleClass( int Init = 0 )
        {
            Value = new int( Init );
        }

        ~SampleClass( void )
        {
            delete Value;
            Value = NULL; // Is this pointless?
        }

        int *Value;
};

Говоря о классах, когда мне следует использовать ключевое слово explicit?


person DeadCapacitor    schedule 13.02.2011    source источник
comment
Точная копия Стоит ли устанавливать указатели на NULL в деструктор? [Я согласен на 100 % с ответом Майкла Берра, который выделен жирным шрифтом: Не делайте этого.]   -  person James McNellis    schedule 13.02.2011
comment
Использование explicit объясняется в Что означает явное ключевое слово в C++?   -  person James McNellis    schedule 13.02.2011
comment
Спасибо за ссылки Джеймс :)   -  person DeadCapacitor    schedule 13.02.2011


Ответы (4)


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

person EvilTeach    schedule 13.02.2011
comment
Но память об объекте не стирается. И если у вас есть другой указатель на экземпляр объекта SampleClass (что может случиться — по ошибке), вы можете получить доступ к памяти. - person Matěj Zábský; 13.02.2011
comment
@mzabsky Если у вас есть эта проблема, вам лучше использовать более умный указатель, чтобы объект не был удален преждевременно. Пытаться защититься от ошибок в остальной части программы довольно бессмысленно. - person Bo Persson; 13.02.2011

Да, бессмысленно устанавливать указатель на NULL в самом конце деструктора, так как он перестанет существовать, как только вы покинете деструктор.

Вы используете явное ключевое слово, когда хотите избежать неявных преобразований в тип вашего класса. :-)

Например, если MyClass имеет конструктор, принимающий int, и функцию f(const MyClass&), вы можете вызвать f либо как

f(42)

or

f(MyClass(42))

Если вы сделаете конструктор явным, будет работать только последний. Это может уберечь вас от некоторых нежелательных неявных преобразований.

person Bo Persson    schedule 13.02.2011

Это не совсем бессмысленно. Хотя это и правда, что теоретически к этому значению нельзя будет получить доступ снова, установка его в NULL вполне может помочь вам в будущем, если начнутся какие-либо другие махинации.

person Puppy    schedule 13.02.2011
comment
Хотя, если это действительно поможет, это почти наверняка не поможет так сильно, как поможет установка какого-либо привлекающего внимание значения. - person Steve Jessop; 13.02.2011
comment
Нет, NULL специально означает, что я установил это вручную. Это не тоже самое. - person Puppy; 13.02.2011
comment
Значение 0xDEADBEEF делает то же самое, плюс оно передает дополнительный смысл, который я установил и надеюсь, что не увижу его обратно. - person MSalters; 14.02.2011

Указатель лучше установить в NULL.

Если где-то еще в коде вы удалите экземпляр SampleClass, а затем получите доступ к Value (используя другой указатель на тот же экземпляр), вы узнаете, что что-то пошло не так, потому что программа рухнет при разыменовании NULL (поэтому вы будете знать, что обращаетесь к удаленному объекту). ).

В противном случае вы могли бы продолжать использовать удаленный объект и заметить ошибку гораздо позже (когда память будет перезаписана другим объектом). Такие проблемы часто чрезвычайно трудно отладить.

person Matěj Zábský    schedule 13.02.2011
comment
Точно так же можно посоветовать никогда не устанавливать этот указатель в NULL, если delete снова вызывается для того же указателя, он просто будет работать, игнорируя вызов, и вы не будете знать, что в вашем коде есть скрытая ошибка... - person David Rodríguez - dribeas; 13.02.2011
comment
@David Rodríguez - dribeas Правило состоит в том, чтобы выявлять ошибки как можно скорее = сбой программы при разыменовании значения NULL. - person Matěj Zábský; 13.02.2011
comment
@ Дэвид Родригес, тебе лучше использовать утверждения или исключения для этого - person whyleee; 13.02.2011
comment
Это просто неправильно: разыменование указателя на объект, который больше не существует, — это только один из видов ошибок, которые могут возникнуть в этом случае. Например, если вы delete p; p = NULL; в деструкторе, а затем проверите if (p == NULL), код по-прежнему неверен, и теперь ваша проверка привела к тому, что вы не нашли эту ошибку. Вы обмениваете способность находить ошибки одного вида на возможность находить ошибки другого рода. - person James McNellis; 13.02.2011
comment
Преимущество не установки указателя на NULL заключается в том, что хорошая среда выполнения отладки (например, предоставляемая отладочной кучей Visual C++) заполнит содержимое освобожденной памяти узнаваемым шаблоном, поэтому его легко очевидно, какая ошибка возникает при сбое; по сути, это позволяет вам легче перехватывать большую часть этих ошибок, гораздо больше, чем если бы вы установили p = NULL;. Майкл Берр объясняет это более элегантно в связанном повторяющемся вопросе. - person James McNellis; 13.02.2011