Здравствуйте, Ivroy, Вы писали:
I>Здравствуйте, rus blood, Вы писали:
RB>>Сравнение this с NULL-ом.
I>ну и что? при this == NULL обращение к данным не происходит. I>все грамотно написано.
При выполнении такого кода ,eltn undefined behavior:
CWnd * pWnd = NULL;
pWnd->GetSafeWnd();
[class.mfct.nonstatic] 9.3.1 Nonstatic member functions
1 A nonstatic member function may be called for an object of its class type, or for an object of a class derived
(clause 10) from its class type, using the class member access syntax (5.2.5, 13.3.1.1). A nonstatic member
function may also be called directly using the function call syntax (5.2.2, 13.3.1.1)
— from within the body of a member function of its class or of a class derived from its class, or
— from a mem-initializer (12.6.2) for a constructor for its class or for a class derived from its class. If a nonstatic member function of a class X is called for an object that is not of type X, or of a type derived
from X, the behavior is undefined.
Здравствуйте, gbt, Вы писали:
gbt>При выполнении такого кода будет undefined behavior:
Это в теории. На практике для MSVC подобный трюк замечательно работает. При всех его недостатках (несоответствие стандарту, плохая переносимость и проч.) использование кода становится удобнее.
Hello, adontz, you wrote:
gbt>>При выполнении такого кода будет undefined behavior: > Это в теории. На практике для MSVC подобный трюк замечательно работает. При > всех его недостатках (несоответствие стандарту, плохая переносимость и проч.) > использование кода становится удобнее.
Хм, вы предлагаете в каждом нестатическом методе делать проверку на this == NULL
перед обращением к любым членам и говорите, что это удобнее...
А если вы предлагаете использовать подобную технику только с классми MFC, в
которых эти проверки делаются, то вскоре возникнет проблема: вы случайно
попытаетесь вызвать метод не-MFC класса для NULL — указателя... ИМХО, лучше
использовать единые правила и стиль программирования во всем проекте. Как только
возникает разделение, начинаются проблемы, связанные с расплывчатостью границ
данного разделения...
ИМХО это аналогично передачи в качестве ссылки разименованного нулевого
указателя — теряется все преимущество ссылки...
Здравствуйте, gbt, Вы писали:
gbt>Хм, вы предлагаете в каждом нестатическом методе делать проверку на this == NULL gbt>перед обращением к любым членам и говорите, что это удобнее...
Нет, нет ни в коем случае.
Я говорю о другом. Пусть некоторый класс имеет смысл указателя. Я говорю не об умных указателях, а например об элементах списка или узлах дерева, которые по сути своей указатели.
Пример — деструктор элемента двоичного дерева
// было
~CBinTreeElement()
{
if (!this->IsNull(this->lpCLeft)) delete this->lpCLeft;
if (!this->IsNull(this->lpCRight)) delete this->lpCRight;
}
// хочу
~CBinTreeElement()
{
if (!this->lpCLeft->IsNull()) delete this->lpCLeft;
if (!this->lpCRight->IsNull()) delete this->lpCRight;
}
Код становится короче, понятнее и нередко эффективнее
Здравствуйте, adontz, Вы писали:
A>Здравствуйте, gbt, Вы писали:
gbt>>Хм, вы предлагаете в каждом нестатическом методе делать проверку на this == NULL gbt>>перед обращением к любым членам и говорите, что это удобнее...
A>Нет, нет ни в коем случае. A>Я говорю о другом. Пусть некоторый класс имеет смысл указателя. Я говорю не об умных указателях, а например об элементах списка или узлах дерева, которые по сути своей указатели. A>Пример — деструктор элемента двоичного дерева A>
A>// было
A> ~CBinTreeElement()
A> {
A> if (!this->IsNull(this->lpCLeft)) delete this->lpCLeft;
A> if (!this->IsNull(this->lpCRight)) delete this->lpCRight;
A> }
A>// хочу
A> ~CBinTreeElement()
A> {
A> if (!this->lpCLeft->IsNull()) delete this->lpCLeft;
A> if (!this->lpCRight->IsNull()) delete this->lpCRight;
A> }
A>
A>Код становится короче, понятнее и нередко эффективнее
В данном примере, вероятно, короче, понятнее и эффективнее будет
если только понятие IsNull не определено как { return this == reinterpret_cast<CBinTreeElement*>(0xDEADBEEF); }, а под нулём понимается настоящий null pointer value [4.10.1].
Здравствуйте, Centaur, Вы писали:
C>если только понятие IsNull не определено как { return this == reinterpret_cast<CBinTreeElement*>(0xDEADBEEF); }, а под нулём понимается настоящий null pointer value [4.10.1].
Нет, в том-то всё и дело, что null это был именно, не null pointer value, а указатель на специально созданный элемент.