Тема: Где хранить свои данные в ARX приложении?

Вопрос, скорее, идеолгоический, чем практический:
где хранить свои внутренние данные в ARX-приложении?
Речь идет о приложении, созданном с помощью AppWizard'a c поддержкой MFC.
На первый взгляд для этого предназначен класс CDocData, экземпляр которого создается в единственном экземпляре. Но это на первый взгляд: в процессе отладки получается, что этот объект (отчего-то?) создается и удаляется несколько раз, т.е. у меня конструктор вызывался несколько раз. Действительно ли CDocData предназначен для хранения внутренних данных, или я зря так думаю?
Поделитесь опытом организации хранения внутренних данных. Все мои данные собраны в одном классе, экземпляр которого должен быть создан в единственном экземпляре и существовать все время, пока ARX приложение загружено. К этому экземпляру должен быть доступ из функций, связанных с новыми командами AutoCAD'а (которые я создаю опять-таки с помощью AppWizarda). Спасибо за внимание.

Re: Где хранить свои данные в ARX приложении?

На способ хранения, насколько мне известно,  оказывает большое влияние тип приложения. Если это приложение типа SDE, то данные можно хранить, где угодно,  и как угодно (в пределах разумного,  разумеется). В случае с MDE приложением  удобнее инкапсулировать глобальные данные, в каком либо классе, что позволяет проще организовать свою копию данных  для каждого загруженного в Автокад чертежа. Если же MDE приложение работает по типу  SDE, то дело вкуса, как и где,  хранить свои данные.

Обычно при работе в режиме  MDE может создаваться несколько объектов этого класса и для манипулирования ими используется другой объект, производный  от базового класса AcApDocManagerReactor.  Его функции позволяют манипулировать,  в том числе и общими данными программы. Если работать без Визарда, то все эти манипуляции надо отслеживать самому.
 
А при использовании Визарда  генерируется класс CDocData, который при помощи  класса AsdkDataManager (это его чл. Функции  ?виноваты? в том, что конструктор CdocData у тебя  вызывался несколько раз), описанного в StdArx.h, автоматизирует этот процесс, т.е.  позволяет хранить свои данные для каждого документа и одновременно занимается процедурой загрузки, выгрузки документа, переключения с документа на документ, активизацией и т.п.

Re: Где хранить свои данные в ARX приложении?

Т.е. свои данные я могу хранить как члены класса CDocData и обращаться к ним через интерфейс AsdkDataManager? (у меня сейчас нет под руком моего проекта, но речь идет о функции, возвращающей экземпляр класса СDocData).

Правильно я понимаю, что в одном чертеже в приложении, созданном AppWizard"ом, существует только один экземпляр класса CDocData?

Но у меня многократный вызов конструктора CDocData происходил в одном чертеже Автокада. Я не производил создание новых чертежей и переключение между ними.

Re: Где хранить свои данные в ARX приложении?

Мне кажется, что их лучше хранить в объекте типа  CdocData. А AsdkDataManager -  template класс,  производный от AcApDocManagerReactor, который и обеспечивает переключение между данными для различных документов(б.д. чертежей + данных программы).

Экземпляр класса  я думаю один(несколько бы VC вряд ли спокойно стерпела), а переменных этого класса(создаваемых динамически при участии AcApDocManagerReactor), думаю, что столько, сколько загружено чертежей(т .е.  по сути,  документов). 

В свете сказанного, мне тоже не очень понятно, почему происходит многократный  вызов конструктора CDocData при работе с одним чертежом Автокада.

Re: Где хранить свои данные в ARX приложении?

У меня происходит следующее: в моем приложении создана команда oaprprofaddvertex:

void oaprprofaddvertex()
{
    // TODO: Implement the command
                 /* ........ */
    DocVars.docData().Profile->AddVertex(Vertex1,0);
                 /* ........ */
}

В класс CDocData добавлено поле
/*......*/
public:
    CPrfProfile* Profile;
/*......*/

Которое инициируется в конструкторе CDocData() и уничтожается в ~CDocData();

По моему разумению CDocData должен был создаваться для каждого документа, причем оставаться в памяти в течении работы моего ARX приложения, чтобы я добавлять поля к этому классу и хранить в них свои данные.
Но все совсем не так! Впервые конструктор CDocData вызывается при выполнении
DocVars.docData().Profile->AddVertex(Vertex1,0); ,
когда член класса T& AsdkDataManager::docData() возвращает T& (в моем случае T - это CDocData). И соотетственно удаляется c ~CDocData, когда отрабатывает метод AddVertex члена Profile. Т.е. этот класс вовсе не висит в памяти. Глобальной переменной является лишь экземпляр класса AsdkDataManager, которые и создает (динамически, как и удаляет) экземпляры класса CDocData. Можно предположить, что этот класс (CDocData) создается, верным образом инициализируется и все время находится в памяти только когда создается новый чертеж в AutoCAD"е (при условии что до создания чертежа мое ARX приложение уже загружено), но этого не происходит. (У меня при создании нового чертежа, когда мое ARX приложение уже загружено вообще происходит Access Violation в acad.exe, но это уже, скорее, мои ошибки, хотя я пока не разобрался в причине их появления).

Итог:
1) класс CDocData не имеет экземпляр, который все время находится в памяти, чтобы обеспечить хранение в нем данных для моего приложения.
2) Представитель этого класса (CdocData) создается с помощью метода класса AsdkDataManager. Причем создается "на лету", т.е. возвращаясь по значению  методом
T& AsdkDataManager::docData().

Итоговый вопрос: как организовать хранение данных в CDocData (если это возможно), и для чего предназначен этот класс (если хранить в нем данные невозможно, хотя в этом я сомневаюсь).

Re: Где хранить свои данные в ARX приложении?

Да, CdocData создается для каждого документа(б.д. чертежа + данные ARX приложения),  но в памяти остаются не в ?течении работы ? ARX приложения?(что такое  - течение работы?), а до тех пор пока чертеж, соответствующий данному документу загружен в Автокад. Этим процессом управляет, как верно тобой замечено,  функции класса AsdkDataManager. Если удаляется чертеж, то срабатывает  реактор и функция documentToBeDestroyed удаляет документ(и CdocData, естественно) ему соответствующий.
Есть еще один крайний случай,  когда все данные будут потеряны - выгрузка ARX приложение, но это, наверное,  не самый интересный случай.

Что касается  выводов, то  я согласен только с выводом ? 2. А для того  чтобы убедиться в том, что CdocData именно то место, где следует хранить данные для отдельных документов, мне кажется,  стоит начать с более простого  примера, где в качестве данных используется какая-нибудь  переменная стандартного типа, а потом уже перейти к работе со своими данными.

Re: Где хранить свои данные в ARX приложении?

В какие моменты должны срабатывать конструткор и деструктор класcа CDocData?

Я запускаю AutoCAD, загружаю свое ARX приложение. В момент загрузки управление передается в мое приложение, где я регистрирую новые команды. В этот же момент мне нужно инициализировать свои глобальны переменные, которые будут использоваться обработчиками зарегистрированных команд. Причем этой глобальной переменной является экземпляр моего класса. Где мне описать пременные моего приложения, чтобы они были связаны с каждым документом (б.д. чертежа)? Сделать это в классе CDocData или нет? Об этом и разговор.

Расскажите, где в ваших программах вы описывали свои данные. Хочется понять идеологию (в WINAPI своя идеология, в MFC - своя, а какова идеология конструирования программы в ObjectARX?).

Re: Где хранить свои данные в ARX приложении?

1.    Конструктор должен срабатывать в момент создания объекта класса CdocData с помощью оператора new, а деструктор в момент уничтожение этого объекта с помощью оператора delete(как это не банально звучит). И то и другое происходит в недрах объекта созданного на основе класса AcApDocManagerReactor.

2.    Сделать это можно где угодно, но Визард Автодесковский предлагает для этого дела CdocData и механизм работы с ним. Именно в объектах этого класса надо хранить объекты своего класса. См. комментарии Визарда, вставленные в тело программы.  Инициализировать можно только те документы, которые загружены. Если процедура инициализации каждого документа уникальна, то этот момент следует учесть при создании процедуры инициализации данных  и с помощью функций класса AcApDocManagerReactor отслеживать появление новых и удаление каких-то документов.


3.     По моему мнению,  идеология  ARX MDE  похожа на MDI идеологию в MFC. А какова она на самом деле, лучше Визарда никто не скажет. См. тексты сгенерированных им программ. В большинстве же своих приложений я не пользуюсь услугами Визарда. Особых причин на это кроме привычки, пожалуй, нет. Если значение данных не зависят от того,  какой загружен чертеж, то храню эти данные в  глобальных переменных, а  если для каждого чертеже нужен свой экземпляр данных, то в переменных типа  CdocData.