Почему многие из GUI CObjects, т. Е. (CButton) должны быть помещены в кучу, а не в стек? - PullRequest
2 голосов
/ 01 февраля 2012

Если я пытаюсь определить кнопку GUI CButton как CButton btn;, я получаю ошибку->, потому что я пытался поместить ее в стек

Но если я делаю CButton *btn = new CButton(); Это работает, и это ставится накуча.

Почему я не могу поместить объекты CButton в стек?

Ответы [ 4 ]

4 голосов
/ 01 февраля 2012

В MFC есть общая идиома, которую я больше нигде не видел.Можно создать «временный» объект, который будет очищен автоматически.Очистка происходит на определенных этапах обработки MFC, таких как цикл обработки сообщений.

CButton * btn = (CButton *) FromHandle(hwnd);

Функция FromHandle возвращает указатель на объект CWnd, но вы не знаете, откуда этот объект пришелот.Вы не должны пытаться удалить указатель и не полагаться на то, что указатель действителен за пределами текущей области - никогда не сохраняйте его в переменную-член!MFC удалит объект при необходимости.

3 голосов
/ 01 февраля 2012

Это вопрос продолжительности хранения.Используя MFC, цель CButton состоит в том, чтобы пользователь мог щелкнуть по нему, что генерирует событие, которое вы затем можете обработать.Все это указывает на то, что время жизни CButton должно превышать время жизни функции, которая его создает.В типичном диалоговом классе MFC (CDialog) CButton является переменной-членом, поэтому его время жизни - это время жизни экземпляра класса.Если вместо этого вы объявите переменную CButton в конструкторе, она выйдет из области видимости и будет уничтожена после завершения работы конструктора.

В некоторых необычных ситуациях вам может потребоваться создать кнопки на основе решения, неизвестного до выполнения.-время.В этом случае, приведенный выше комментарий о неиспользовании голого «нового» важен.Используйте умный указатель (или контейнер умных указателей), чтобы удерживать созданный CButton *, чтобы он автоматически очищался.Эти умные указатели, или контейнер, должны быть созданы в области видимости класса.

1 голос
/ 01 февраля 2012

1) Как ответили многие другие, это связано с областью действия переменной.Делая его локальным для функции, он завершает свою жизнь при выходе из функции.

2) Пространство стека намного более ограничено, чем пространство кучи, особенно с несколькими потоками.Типичный процесс win32 занимает менее одного мегабайта стека, но может иметь тысячи мегабайт кучи.

1 голос
/ 01 февраля 2012

Я не знаю MFC, но я предполагаю, что ваш CButton, размещенный в стеке, выходит за пределы области видимости, поэтому он уничтожается.
Доступ к этому экземпляру кнопки из другого места вызоветнарушение доступа.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...