#c #initialization #glut
#c #инициализация #перенасыщение
Вопрос:
Программист-новичок на C все еще здесь.
Я использую компилятор VC VS2008 и библиотеку перенасыщения. Все работает нормально и актуально (я знаю, что в 2010 году только cba из-за соображений поддержки XNA (C #))
Хорошо, на этот раз у меня есть вопрос, связанный с кодом, но я могу заставить код работать. Чего я не могу сделать, так это выяснить, что происходит под капотом. Это то, что я хотел бы выяснить.
Предположим, что все работает, потому что очевидно, что во время выполнения это работает!
Вот код (сведенный к тому, что на самом деле выполняется на его голом ядре, чтобы ускорить это)
#include "stdafx.h"
#include "Controller.h"
#include "glut.h"
#include <iostream>
void main(int argc, char** argv)
{
glutInit(amp;argc, argv);
//controller_ptr->InitController(); <---- no link to controller-->DrawScene
//INIT GLUT
//glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGB | GLUT_DEPTH);
//glutInitWindowSize(400, 400); //Set the window size
//glutCreateWindow("Some Program");
//INIT RENDERING
glEnable(GL_DEPTH_TEST);
glutDisplayFunc(drawScene);
glutKeyboardFunc(handleKeypress);
glutReshapeFunc(handleResize);
glutMainLoop();
}
Вы можете подумать, эй, вы прокомментировали код инициализации.
Действительно, да. Угадайте, что, это все еще работает! Почему? Я действительно не знаю перенасыщения, за исключением BBQ’s so ye …. <—- Это может быть хорошим моментом для вас, чтобы вызвать сбой, если таковой имеется
У меня есть класс drawscene с этим методом
void DrawScene::initGlut()
{
//Enables depth culling/front face culling?????? <----- what about that, some depth thingy was involved is all I'm sure of
glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGB | GLUT_DEPTH);
glutInitWindowSize(400, 400); //Set the window size
glutCreateWindow("Some Program");
}
Когда я комментирую это и раскомментирую одно из основных, результат тот же. Я не комментирую none, glut говорит, что инициализация выполняется дважды, я не комментирую ни то, ни другое, инициализация не выполнена, все идет кувырком. Таким образом, единственным логическим выводом было бы сказать, что этот метод вызван, верно?
Существует множество других методов и классов, но нет экземпляра класса displayescene или класса controller. Я могу прокомментировать includes, и он сделает все то же самое.
Есть ли какая-то часть дизайна, которую я не понимаю в MSBuild или разработке VC , которая позволяет методам просеивать по некоторому потоку, о котором я не знаю? Насколько мне известно, если я не создаю экземпляр класса, это не имеет значения, по крайней мере, это нестатические члены. Итак, как тогда этот код, являющийся активным или неактивным в этом элементе, может повлиять на мою программу?
Вероятно, забыл что-то невероятно глупое, но я предпочел бы узнать это самостоятельно. в любом случае, хорошая часть того, что я новичок, заключается в том, что мне наплевать на то, что я падаю ничком и пытаюсь снова, так что продолжайте с комментариями ^^
Заранее большое вам спасибо!
РЕДАКТИРОВАТЬ: Что за? Теперь консоль без каких-либо изменений в коде один раз сообщила о двойном вызове init с основным init в комментарии и тем, который в drawscene отсутствует в комментарии…Я очень сильно сбит с толку.
ПРАВКА 2: 14:45 29.08.2010
Хорошо, я кое-что нашел….
Конструктор в drawscene вызывает методы initGlut и initRendering класса. Контроллер создает указатель на кучу, содержащую находящийся там объект drawScene, который заставляет методы запускать код инициализации.
Однако контроллер не включен в main и не создан его экземпляр. Этот код drawScene запускается перед запуском main, и могу ли я затем сделать вывод, что проблема заключается в самой сборке, поэтому мне следует избегать инициализации кода в конструкторах?
ПРАВКА 3: 15:02 29.08.2010
Найдено другое, двойной вызов происходит, когда активным кодом инициализации является только drawScene. Может ли быть так, что каждое включение drawscene заставляет код конструктора запускать код инициализации и вызывать двойную инициализацию?
Ответ №1:
Почему бы не установить точку останова в вашем коде инициализации, а затем подняться по стеку вызовов, чтобы увидеть, где она вызывается?
Пройдите через это медленно, и я бы предположил, что вы найдете источник..
Редактировать: хорошей практикой является исключение инициализации таких вещей, как библиотеки, из конструктора. Лично я бы просто проверил, что glut был инициализирован в конструкторе, если это требуется, и выдал исключение, если оно не обнаружено.
Комментарии:
1. Ну, это происходит внутри Drawscene до того, как он попадает в одну строку кода в main, так что это означает, что это препроцессор, верно?
2. Нет, статическое построение объекта — это единственное, что выполняется перед main. Если вы находитесь в библиотеке / DLL, другой код может выполняться перед main.
3. Что тогда насчет includes? Практически все, что имеет # впереди, является директивой препроцессора, верно? Я мало что знаю о предварительной обработке, только то, что это всегда шаг 1 в цепочке компиляции. Итак, исходя из причудливой мысли, что, если все включения в сочетании с кодом конструктора приведут к вызову метода? Будет ли это тогда предварительным основным кодом?
Ответ №2:
по-видимому, эти изящные указатели были не частью объекта, а глобальными, например C # VS C 😛
Глобальное объявление содержимого в файлах cpp ПЛОХОЕ, урок усвоен