#c
#c
Вопрос:
Я не хочу использовать указатели, когда мне это не нужно, но вот в чем проблема: в приведенном ниже коде, если я удаляю звездочку и делаю level
просто object
, и, конечно, удаляю строку level = new Level;
, я получаю ошибку времени выполнения, причина в том, что level
она затем инициализируется в первой строке, ДО initD3D
и init_pipeline
— методы, которые настраивают проекцию и представление для использования. Вы видите, проблема в том, что level
использует эти две вещи, но при первом выполнении я получаю null
исключение указателя.
Является ли это просто обстоятельством, когда ответ заключается в использовании указателя? У меня была эта проблема раньше, в основном кажется крайне неприятным, что, когда тип класса не принимает аргументов, вы по сути инициализируете его там, где вы его объявляете …. или я ошибаюсь в этой последней части?
Level* level;
D3DMATRIX* matProjection,* matView;
//called once
void Initialise(HWND hWnd)
{
initD3D(hWnd);
init_pipeline();
level = new Level;
}
Я пришел из c #, а в c # вы просто объявляете имя со строкой Level level
; аргументы или нет, вам все равно придется его инициализировать в какой-то момент.
Комментарии:
1. Это не имеет никакого отношения к тому, имеет ли
Level
определяемый пользователем конструктор или его конструкторы принимают параметры. Проблема в том, что глобальные переменные инициализируются передmain
вводом. Вы бы увидели точно то же самое, если бы вы написалиLevel level(1,2,3);
, соответствующий конструктор был бы вызван доinitD3D
иinit_pipeline
.
Ответ №1:
Вы правы, что если вы:
Level level;
level
в этот момент будет создан экземпляр then. Это потому, что приведенное выше выражение, которое кажется глобальным, является не просто объявлением, но и определением.
Если это вызывает у вас проблемы, потому Level
что создается экземпляр до создания экземпляра чего-то другого, то вы столкнулись с классической причиной, по которой глобальные переменные отстой.
Вы пытались решить эту проблему, создав level
указатель, а затем «инициализировав» его позже. Что может вас удивить, так это то, что level
экземпляр все еще создается в той же точке. Теперь разница заключается в типе level
. Это Level
больше не a; теперь это указатель на level
. Если вы проверите значение level
при вводе вашего кода Initialize
, вы увидите, что оно имеет значение NULL .
Он имеет значение NULL вместо мусорного значения, потому что глобальные переменные инициализируются статически, что в данном случае означает инициализацию нулем.
Но все это несколько связано с реальной проблемой, которая заключается в том, что вы используете глобальные переменные в первую очередь. Если вам нужно создавать экземпляры объектов в определенном порядке, создавайте их в этом порядке. Не используйте глобальные переменные, и вы можете обнаружить, что при этом вам также не нужно использовать указатели.
Комментарии:
1. «у него есть значение — но это значение является мусором» — это не мусор, потому что глобальные переменные инициализируются нулем.
Ответ №2:
Является ли это просто обстоятельством, когда ответ заключается в использовании указателя
Да, в принципе.