Russian Qt Forum

Программирование => С/C++ => Тема начата: Scotty от Октябрь 25, 2009, 09:50



Название: Как сделать аттрибут собственного класса
Отправлено: Scotty от Октябрь 25, 2009, 09:50
Доброго времени суток!
Вопрос может показаться немного туповатым но я - не понимаю как оно должно работать.
Предположим есть ситуация:
Код
C++ (Qt)
class B{
public:
 B();
 QString getText();
}
 
class A{
public:
 A();
 B attrB;
}
 
Что собственно хочется:
Когда я разименовываю класс A получить внедркнный объект класса B, иными словами:
Код
C++ (Qt)
QString vSomeText = A->attrB.getText();
Как такое провернуть, непонимаю .... помогите пожалуйста, перерыл много чего, прочитал и про вложеные классы и про friend классы и исходники в Qt смотрел и ничего не понял ... как такое сделать?


Название: Re: Как сделать аттрибут собственного класса
Отправлено: BRE от Октябрь 25, 2009, 10:07
Код
C++ (Qt)
A a;
QString str = a.attrB.getText();
 
A *a = new A;
QString str = a->attrB.getText();
 


Название: Re: Как сделать аттрибут собственного класса
Отправлено: Scotty от Октябрь 25, 2009, 10:42
Всё бы хорошо, но вот компилятор со мною не согласен, пишет что я неверно со ссылками работаю, надо было сразу контекст описывать конкретно, а я написал абстрактно.
Вот так вот пишу:
Заголовочный файл:
Код
C++ (Qt)
#ifndef TESTSUITE_H
#define TESTSUITE_H
#include <QString>
#include <QDomDocument>
#include <QDomNode>
#include <QFileInfo>
 
 
class Test;
class TestSuite;
 
class Test{
public:
   Test();
   Test(QDomElement aTest);
   bool setContent(QDomElement aTest);
   int getTotall();
protected:
   QDomElement * gTest;
};
 
class TestSuite{
public:
   TestSuite();
   int openFile(QString aFileName);
   Test getTest(int aTestItem);
private:
   QString gFilePath;
   QString gFileName;
 
protected:
   QDomDocument * gTestSuite;
 
};
#endif // TEST_H
 

В реализации пишу:
Код
C++ (Qt)
   /********************************
Implementation of class Test
********************************/

Test::Test(){
   gTest = new QDomElement;
}
 
Test::Test(QDomElement &aTest){
   gTest = new QDomElement(aTest);
}
 
bool Test::setContent(QDomElement aTest){
   if (!aTest.isNull()){
       gTest = aTest;
       return true;
   } else
       return false;
}
 
int Test::getTotall(){
   return gTest->attributes().namedItem("totall").nodeValue().toInt();
}
 

В результате компилятор ругается :
E:/Exam/Exam/ExamTest/TestSuite.cpp:47: error: conversion from `Test*' to non-scalar type `Test' requested

У меня только один вопрос, как мне сделать при данном раскладе результат метода TestSuite::getTest(int index), в класс Test.
Это надо чтобы я сделал примерно так:
Код
C++ (Qt)
   TestSuite * vTs = new TestSuite;
   qDebug() << vTs->openFile(QString("E:/Exam/Exam/ExamTest/2.xml"));
   qDebug() << vTs->getTest(1).getTotal();
 
и на консоли получить требуемый аттрибут в XML  ???


Название: Re: Как сделать аттрибут собственного класса
Отправлено: BRE от Октябрь 25, 2009, 10:46
Код
C++ (Qt)
bool Test::setContent(QDomElement aTest){
   if (!aTest.isNull()){
       *gTest = aTest;
       return true;
   } else
       return false;
}
 


Название: Re: Как сделать аттрибут собственного класса
Отправлено: Scotty от Октябрь 25, 2009, 10:51
Простите но ругается он на этот кусок кода:
Код
C++ (Qt)
Test TestSuite::getTest(int aTestItem){
   Test vTest = new Test(gTestSuite->firstChild().childNodes().item(aTestItem).toElement());
   return vTest;
}
 
С такой вот ошибкой:
  E:/Exam/Exam/ExamTest/TestSuite.cpp:47: error: conversion from `Test*' to non-scalar type `Test' requested


Название: Re: Как сделать аттрибут собственного класса
Отправлено: BRE от Октябрь 25, 2009, 10:54
Код
C++ (Qt)
Test *TestSuite::getTest(int aTestItem){
   Test *vTest = new Test(gTestSuite->firstChild().childNodes().item(aTestItem).toElement());
   return vTest;
}
 
new Class() - возвращает указатель.

Если хочешь возвращать по значению, то в классе Test нужно определить конструктор копирования и оператор =.
Код
C++ (Qt)
Test TestSuite::getTest(int aTestItem){
   Test vTest(gTestSuite->firstChild().childNodes().item(aTestItem).toElement());
   return vTest;
}
 


Название: Re: Как сделать аттрибут собственного класса
Отправлено: Scotty от Октябрь 25, 2009, 10:56
 ;D Вернул ссылку и всё ... вроде заработало :)


Название: Re: Как сделать аттрибут собственного класса
Отправлено: spectre71 от Октябрь 25, 2009, 10:57
Простите но ругается он на этот кусок кода:
Код
C++ (Qt)
Test TestSuite::getTest(int aTestItem){
   Test vTest = new Test(gTestSuite->firstChild().childNodes().item(aTestItem).toElement());
   return vTest;
}
 
С такой вот ошибкой:
  E:/Exam/Exam/ExamTest/TestSuite.cpp:47: error: conversion from `Test*' to non-scalar type `Test' requested



Код
C++ (Qt)
Test TestSuite::getTest(int aTestItem){
   Test* vTest = new Test(gTestSuite->firstChild().childNodes().item(aTestItem).toElement());
   return *vTest;
}
 
 


Название: Re: Как сделать аттрибут собственного класса
Отправлено: BRE от Октябрь 25, 2009, 11:00
Код
C++ (Qt)
Test TestSuite::getTest(int aTestItem){
   Test* vTest = new Test(gTestSuite->firstChild().childNodes().item(aTestItem).toElement());
   return *vTest;
}
 
Ох с удалением этого объекта еще вопросы возникнут.  :)


Название: Re: Как сделать аттрибут собственного класса
Отправлено: Scotty от Октябрь 25, 2009, 11:04
Ага, вот я и говорю вернул ссылку и всё стало волшебно работать, вот только немного не понимаю почему когда пишу результат - класс а возвращаю не экземпляр класса а ссылку на него  ??? Это я конечно могу принять на веру и посчитать что так надо, но может есть тому логичное объяснение?


Название: Re: Как сделать аттрибут собственного класса
Отправлено: Scotty от Октябрь 25, 2009, 11:07
Цитировать
Ох с удалением этого объекта еще вопросы возникнут. :)
А ведь и вправду, как я его потом удалять буду если я ссылку на него один раз получу, воспользуюсь тем чем надо а что дальше ??? :) Как мне его из памяти то убрать ??? При следующем обращении создастся новый объект и вернется ссылка на новый экземпляр  :o


Название: Re: Как сделать аттрибут собственного класса
Отправлено: BRE от Октябрь 25, 2009, 11:15
Попробуй так переписать:
Код
C++ (Qt)
class Test{
public:
   Test();
   Test( const QDomElement &aTest );
   bool setContent( const QDomElement &aTest );
   int getTotall();
protected:
   QDomElement gTest;
};
 
Test::Test()
{
}
 
Test::Test( const QDomElement &aTest ) :
gTest( aTest )
{
}
 
bool Test::setContent( const QDomElement &aTest )
{
   if (!aTest.isNull()){
       gTest = aTest;
       return true;
   } else
       return false;
}
 
int Test::getTotall(){
   return gTest.attributes().namedItem("totall").nodeValue().toInt();
}
 

Код
C++ (Qt)
Test TestSuite::getTest(int aTestItem){
   Test vTest( gTestSuite->firstChild().childNodes().item(aTestItem).toElement() );
   return vTest;
}
 


Название: Re: Как сделать аттрибут собственного класса
Отправлено: spectre71 от Октябрь 25, 2009, 11:26
Цитировать
Ох с удалением этого объекта еще вопросы возникнут. :)
А ведь и вправду, как я его потом удалять буду если я ссылку на него один раз получу, воспользуюсь тем чем надо а что дальше ??? :) Как мне его из памяти то убрать ??? При следующем обращении создастся новый объект и вернется ссылка на новый экземпляр  :o

Естественно!
Вариантов как правильно сделать много, все зависит от твоей задачи.

Код
C++ (Qt)
Test TestSuite::getTest(int aTestItem){
   Test vTest(...);
   return Test(...);
}
 
////////////
 
Test* TestSuite::getTest(int aTestItem){
   return new Test(...);
}
 
////////////
 
class TestSuite {
 ...
 ...
 Test* tmpTest;
 ...
 ...
}
 
Test& TestSuite::getTest(int aTestItem){
   if(tmpTest) {delete tmpTest;}
   tmpTest = new Test(...);
   return *tmpTest;
}
 


ИТД...


Название: Re: Как сделать аттрибут собственного класса
Отправлено: Scotty от Октябрь 25, 2009, 11:27
Немного подрихтовал, но при этом компилятор ругается на
Код
C++ (Qt)
Test::Test(const QDomElement &aTest){
   gTest(aTest);
}
 
E:/Exam/Exam/ExamTest/TestSuite.cpp:61: error: no match for call to `(QDomElement) (const QDomElement&)'


Название: Re: Как сделать аттрибут собственного класса
Отправлено: BRE от Октябрь 25, 2009, 11:29
Немного подрихтовал, но при этом компилятор ругается на
Подрихтовал?  ;)
Код
C++ (Qt)
Test::Test( const QDomElement &aTest ) :
       gTest( aTest )
{
}
 


Название: Re: Как сделать аттрибут собственного класса
Отправлено: Scotty от Октябрь 25, 2009, 11:32
Немного подрихтовал, но при этом компилятор ругается на
Подрихтовал?  ;)
Код
C++ (Qt)
Test::Test( const QDomElement &aTest ) :
       gTest( aTest )
{
}
 
Да блин далеко мне ещё до нормального понимания С++ :) Спасибо большое !!! Особенно за терпимость к новичкам.


Название: Re: Как сделать аттрибут собственного класс&#
Отправлено: Scotty от Октябрь 27, 2009, 23:04
Хм, однако есть маленький вопрос, это если делать так, то получается что при каждом обращении будет передаваться объект в тот класс что я получаю методом, так вот, я попробовал переписать так как вы сказали
Немного подрихтовал, но при этом компилятор ругается на
Подрихтовал?  ;)
Код
C++ (Qt)
Test::Test( const QDomElement &aTest ) :
       gTest( aTest )
{
}
 
И однако есть проблема, объекты из памяти не уходят, программа жрет память в арифметической прогрессии, на каждую итерацию сжирает по 7 Мб памяти (а итераций у меня мно-о-о-о-ого), так не годиться ... может есть соображения как обойти это?


Название: Re: Как сделать аттрибут собственного класса
Отправлено: BRE от Октябрь 27, 2009, 23:09
Покажи свой код, где происходят итерации.


Название: Re: Как сделать аттрибут собственного класса
Отправлено: Scotty от Октябрь 27, 2009, 23:15
Код
C++ (Qt)
   LogSuite * vLogSuite = new LogSuite();
   vLogSuite->openFile("E:/log/RootLogData.dat");
   //qDebug() << "LogPath: " + vLogSuite->getFileName();
 
   ui->textBrowser->append(tr("Папка : ")+vLogSuite->getFilePath());
   ui->textBrowser->append(tr("Файл: ")+vLogSuite->getFileName());
   char buff[10];
   itoa(vLogSuite->getTotalItemsCount(), buff, 10);
   ui->textBrowser->append(tr("Количество элементов: ")+ buff);
   ui->textBrowser->append(tr("== Тестовый элемент 1 =="));
   ui->textBrowser->append(tr("Путь к файлу: ") + vLogSuite->getLogItem(0).getFileName());
   ui->textBrowser->append(tr("Владелец: ") + vLogSuite->getLogItem(0).getOwnerMoniker());
   ui->textBrowser->append(tr("Имя: ") + vLogSuite->getLogItem(0).getName());
 
   itoa(vLogSuite->getLogItem(0).getStatus(), buff, 10);
   ui->textBrowser->append(tr("Статус: ") + buff);
 
   ui->textBrowser->append(tr("Идентификатор : ") + vLogSuite->getLogItem(0).getMoniker());
   ui->textBrowser->append(tr("Ссылка на тест : ") + vLogSuite->getLogItem(0).getTest());
   ui->textBrowser->append(tr("Ключ данных : ") + vLogSuite->getLogItem(0).getPersistentDataKey());
   ui->textBrowser->append(tr("Ключ проекта : ") + vLogSuite->getLogItem(0).getProjectKey());
   ui->textBrowser->append(tr("Относительный путь : ") + vLogSuite->getLogItem(0).getRelativeFileName());
   if (vLogSuite->getLogItem(0).hasChildren()){
     ui->textBrowser->append(tr("Есть дети : ДА"));
     itoa(vLogSuite->getLogItem(0).getChildrenCount(), buff, 10);
     ui->textBrowser->append(tr("Количество детей : ") + buff);
   }
   else
     ui->textBrowser->append(tr("Есть дети : Нет"));
   delete vLogSuite;
 


Название: Re: Как сделать аттрибут собственного класса
Отправлено: BRE от Октябрь 27, 2009, 23:18
Этот код внутри цикла вызывается? Где итерации?  ;)


Название: Re: Как сделать аттрибут собственного класса
Отправлено: BRE от Октябрь 27, 2009, 23:21
Кстати переводить число в строку проще штатными методами:
Код
C++ (Qt)
QString strNum = QString::number( 123 );
 


Название: Re: Как сделать аттрибут собственного класса
Отправлено: Scotty от Октябрь 27, 2009, 23:29
То что цикла - нет, то я понимаю :) Я просто итерацию запихнул в слот и эмулирую так сказать её нажатием на кнопку, жму 5 раз и 5*7=35 мб. как не бывало  :) Если я это в обработчик моих логов затолкаю, то там я думаю прощай вся моя оперативка ...


Название: Re: Как сделать аттрибут собственного класса
Отправлено: BRE от Октябрь 27, 2009, 23:30
То что цикла - нет, то я понимаю :) Я просто итерацию запихнул в слот и эмулирую так сказать её нажатием на кнопку, жму 5 раз и 5*7=35 мб. как не бывало  :) Если я это в обработчик моих логов затолкаю, то там я думаю прощай вся моя оперативка ...
Покажи где создаются объекты Test, где удаляются и т.д.


Название: Re: Как сделать аттрибут собственного класс&#
Отправлено: Scotty от Октябрь 27, 2009, 23:40
Такс, вот заголовок двух классов (остальные сделаны по аналогии):
Код
C++ (Qt)
class LogItem
{
public:
   LogItem(const QDomElement &aLogItem);
   QString getFileName();
   QString getOwnerMoniker();
   QString getName();
   int getStatus();
   QString getMoniker();
   QString getTest();
   QString getPersistentDataKey();
   QString getProjectKey();
   QString getRelativeFileName();
   bool hasChildren();
   int getChildrenCount();
   LogItemChildren getChildren(int aChildrenindex);
  // QString test(); //for debug
private:
   void setRelativePath(QString aPath);
protected:
   QDomElement gLogItem;
   QString gLogPath;
friend class LogSuite;
};
 
class LogSuite{
public:
   LogSuite();
   int openFile(QString aFileName);
   void closeFile();
   QString getFilePath();
   QString getFileName();
   int getTotalItemsCount();
   LogItem getLogItem(int aItemIndex);
protected:
   QString gLogPath;
   QString gLogFileName;
   QDomDocument * gLogSuiteDocument;
};
 

Такс, конструкторы классов :

Код
C++ (Qt)
 
LogItem::LogItem(const QDomElement &aLogItem):gLogItem(aLogItem){
 
}
 
LogSuite::LogSuite()
{
   gLogSuiteDocument = new QDomDocument;
}
 
Метод получения объекта
Код
C++ (Qt)
LogItem LogSuite::getLogItem(int aItemIndex){
   LogItem vLogItem( gLogSuiteDocument->lastChild().firstChild().childNodes().item(aItemIndex).toElement());
   vLogItem.setRelativePath(this->gLogPath);
   return vLogItem;
}
 
Хм ... а тут я начинаю смутно понимать что создавать то я создаю а вот удалять ... как и где, оно в таком случае где должно освобождать ресурсы? В деструкторе, но где я его вызову если у меня объект как таковой используется для получения только результата метода? Да и как к нему обратиться то?


Название: Re: Как сделать аттрибут собственного класса
Отправлено: BRE от Октябрь 27, 2009, 23:46
А где удаляется gLogSuiteDocument?
Думаю дело в этом.


Название: Re: Как сделать аттрибут собственного класс&#
Отправлено: Scotty от Октябрь 27, 2009, 23:55
Да Вы вокруг и всюду правы :) Я продеструкторы по рассеиности забыл, просто добавил в деструктор класса LogSuite строку удаления примерно так:
Код
C++ (Qt)
LogSuite::~LogSuite()
{
   delete gLogSuiteDocument;
}
 
и память умеренно стала кушаться (и даже возвращаться системе ;) )... большое спасибо !


Название: Re: Как сделать аттрибут собственного класса
Отправлено: Scotty от Октябрь 28, 2009, 22:35
Наверное не очень в тему, но чтобы не повторяить историю всего этого топика при описании проблемы, хотелось бы задать ещё вопрос. Если я получаю из файла XML строку (она в UTF-8) и сохраняю её в QString'e потом, я прохожу по файлу с помощью тех классов что я описыывал в этом топике и у каждого получаю строку - идентификатор (она должна быть тоже в UTF-8, т.к. берется из того же фала что и та которую я сохранил) и сравниваю с первым значением, но вот проблема - оно не находит совпадений, но совпадения 500% есть я сам руками их нахожу  >:( Незнаю что такое, возможно вопрос опять в кодировке, или я опять глючу ???


Название: Re: Как сделать аттрибут собственного класса
Отправлено: Scotty от Октябрь 30, 2009, 00:12
Хм, однако ответа - нет  :-\ Может всётаки кто нибудь подскажет как мне сравнивать между собою строки взятые из файла??? Я пытался QString::Compare() и == может есть 100%  вариант?


Название: Re: Как сделать аттрибут собственного класса
Отправлено: BRE от Октябрь 30, 2009, 00:26
Хм, однако ответа - нет  :-\ Может всётаки кто нибудь подскажет как мне сравнивать между собою строки взятые из файла??? Я пытался QString::Compare() и == может есть 100%  вариант?
Как ты получаешь из файла строку, как ты ее помещаешь в QString. Покажи код.


Название: Re: Как сделать аттрибут собственного класса
Отправлено: Alex Custov от Октябрь 30, 2009, 01:59
Хм, однако ответа - нет  :-\ Может всётаки кто нибудь подскажет как мне сравнивать между собою строки взятые из файла??? Я пытался QString::Compare() и == может есть 100%  вариант?

всегда приводи минимальный компилируемый код, который 100% воспроизводит проблему. А так гадать можно долго :)


Название: Re: Как сделать аттрибут собственного класс&#
Отправлено: Scotty от Октябрь 30, 2009, 22:33
Ага, простите ... вот код:
Код
C++ (Qt)
QString LogItemChildren::test(){
   QString moniker = gLogItemChildren.attributes().namedItem("value").nodeValue();
   QDomElement nodes(gLogItemChildren.parentNode().parentNode().toElement());
   int i = 0;
   while(i < nodes.childNodes().count()){
       if (getMoniker(nodes.childNodes().item(i).toElement()).compare(moniker, Qt::CaseInsensitive) == 0)
           break;
       i++;
   }
   return getMoniker(nodes.childNodes().item(i).toElement());
}
 
Вот незнаю там по XML файлу бегаю и читаю из него ... но вот не совпадает почему то ...  ???


Название: Re: Как сделать аттрибут собственного класса
Отправлено: BRE от Октябрь 30, 2009, 22:39
А ты поставь в разных местах отладочный вывод (qDebug) и посмотри, что там в строки загружается и что с чем сравнивается.


Название: Re: Как сделать аттрибут собственного класса
Отправлено: Scotty от Октябрь 30, 2009, 23:32
Сделал вывод - правильно выводит  >:( Строго 2 соответствия во всем списке, но при выполнении этого алгоритма - не работает  >:(


Название: Re: Как сделать аттрибут собственного класса
Отправлено: BRE от Октябрь 30, 2009, 23:36
Код
C++ (Qt)
QString LogItemChildren::test(){
   QString moniker = gLogItemChildren.attributes().namedItem("value").nodeValue();
   QDomElement nodes(gLogItemChildren.parentNode().parentNode().toElement());
   int i = 0;
   while(i < nodes.childNodes().count()){
       if (getMoniker(nodes.childNodes().item(i).toElement()).compare(moniker, Qt::CaseInsensitive) == 0)
// Произошло совпадение, выходим из цикла и....
           break;  
       i++;
   }
// возвращаем строку из 5 элемента...
   return getMoniker(nodes.childNodes().item(5).toElement());
}
 
Или я алгоритм не понял?
Что он должен делать?


Название: Re: Как сделать аттрибут собственного класс&#
Отправлено: Scotty от Октябрь 30, 2009, 23:58
Он берет и получает идентификатор (или прозвище как там у меня называется), запоминает и шерстит все ноды которые находятся выше её по иерархии как только находит  - обрывает цикл и возвращает идентификатор нужной ноды. Там структура немного странноватая:
Код:
<node>
  <childs>
    <child moniker="1">
  </childs>
<prp moniker="0"/>
</node>
<node>
  <childs/>
  <prp moniker="1"/>
</node>
Т.е. первый итем - родитель, второй дочерний. Вот второй то мне и надо получить по идентификатору.


Название: Re: Как сделать аттрибут собственного класс&#
Отправлено: BRE от Октябрь 31, 2009, 00:02
Он берет и получает идентификатор (или прозвище как там у меня называется), запоминает и шерстит все ноды которые находятся выше её по иерархии как только находит  - обрывает цикл и возвращает идентификатор нужной ноды.
Он всегда возвращает идентификатор 5 ноды.


Название: Re: Как сделать аттрибут собственного класса
Отправлено: Scotty от Октябрь 31, 2009, 00:04
 ;D Пардон это я неправильно написал, это я так отлаживался


Название: Re: Как сделать аттрибут собственного класса
Отправлено: BRE от Октябрь 31, 2009, 00:14
Попробуй так, посмотри что выводиться на консоль:
Код
C++ (Qt)
QString LogItemChildren::test(){
   QString moniker = gLogItemChildren.attributes().namedItem("value").nodeValue();
   qDebug() << moniker;
 
   QDomElement nodes(gLogItemChildren.parentNode().parentNode().toElement());
   int i = 0;
   while(i < nodes.childNodes().count()){
QString v = getMoniker( nodes.childNodes().item(i).toElement() );
qDebug() << v
       if (v.compare(moniker, Qt::CaseInsensitive) == 0)
return v;
       i++;
   }
   return QString();
}
 

Еще смутило, но может так задумано:
QDomElement nodes(gLogItemChildren.parentNode().parentNode().toElement());


Название: Re: Как сделать аттрибут собственного класса
Отправлено: Scotty от Октябрь 31, 2009, 00:22
Да! Вот только что сам дошел до этого ... там не
Код
C++ (Qt)
QDomElement nodes(gLogItemChildren.parentNode().parentNode().toElement());
, а
Код
C++ (Qt)
QDomElement nodes(gLogItemChildren.parentNode().parentNode().parentNode().toElement());
там на 3 уровня вверх надо подниматься, это именно так и задуманно ... спасибо ещё раз за терпение, просто надо было  попристальнее вглядеться в код ... и в файл с данными  :D


Название: Re: Как сделать аттрибут собственного класс&#
Отправлено: Scotty от Ноябрь 02, 2009, 00:33
Товарищи!!! :) Помогите ещё раз, на сей аз вопрос не очень простой (ну это конечно же для меня :) ). Есть у меня набор классов для работы с XML файлом, они описаны выше, но вот последняя заковыка в том, что  я написал ещё набор классов, которые работают с файлами другого рода, но тоже xml и незнаю как правильно их связать. Вот эти классы:
Код
C++ (Qt)
class LogDescription;
class LogSuite;
class LogItem;
class LogItemChildren;
class LogMessages;
class LogMessage;
 
class LogMessage{
public:
   LogMessage();
   LogMessage(QDomElement aLogMessage);
   ~LogMessage();
   QString getMessage();
private:
    void setRelativePath(QString aPath);
protected:
    QDomElement gLogMessage;
    QString gLogPath;
friend class LogMessages;
};
 
class LogMessages
{
public:
   LogMessages();
   ~LogMessages();
   int openFile(QString aFileName);
   int getMessagesCount();
   QString getFileName();
   QString getFilePath();
   LogMessage getLogMessage(int aLogMessageIndex);
protected:
   QString gLogPath;
   QString gLogFileName;
   QDomDocument * gLogMessagesDocument;
};
 
class LogItemChildren{
public:
   LogItemChildren(const QDomElement &aChildrenItem);
   ~LogItemChildren();
   QString getRelativeFileName();
   QString getChildrenMoniker();
   LogItem getLogItem();
   QString test();
private:
   void setRelativePath(QString aPath);
protected:
   QDomElement gLogItemChildren;
   QString gLogPath;
friend class LogItem;
};
 
class LogItem{
public:
   LogItem(const QDomElement &aLogItem);
   ~LogItem();
   QString getFileName();
   QString getOwnerMoniker();
   QString getName();
   int getStatus();
   QString getMoniker();
   QString getTest();
   QString getPersistentDataKey();
   QString getProjectKey();
   QString getRelativeFileName();
   bool hasChildren();
   int getChildrenCount();
   LogItemChildren getChildren(int aChildrenindex);
   LogMessages getLogMessages();
private:
   void setRelativePath(QString aPath);
protected:
   QDomElement gLogItem;
   QString gLogPath;
friend class LogSuite;
friend class LogItemChildren;
};
 
class LogSuite{
public:
   LogSuite();
   ~LogSuite();
   int openFile(QString aFileName);
   void closeFile();
   QString getFilePath();
   QString getFileName();
   int getTotalItemsCount();
   LogItem getLogItem(int aItemIndex);
protected:
   QString gLogPath;
   QString gLogFileName;
   QDomDocument * gLogSuiteDocument;
};
 
Как видно из заголовков, LogItem::getLogMessages() возвращает экземпляр класса LogMessages. Всё бы было хорошо, но вот описание данных класса LogMessages лежит в другом файле (физически в другом но рядом), так вот не перечитывать же мне каждый раз при вызове метода файл с данными дя этого класса. Идея решения есть - просто хранить в памяти экземпляр класса LogMessages пока не будет уничтожен объект класса LogItem, тогда контекст смениться и естественно смениться ссылка на файл. Создавать думаю надо в конструкторе LogMessages. А вот как это сделать пока не понимаю (глупповат ещё), подкажите пожалуйста как мне увязать сие друг с другом ???


Название: Re: Как сделать аттрибут собственного класса
Отправлено: Scotty от Ноябрь 02, 2009, 19:19
Вот самое плохое, что когда всё сделаешь, перед последним рывком остается какая нибудь заковыка и всё !!! Всё летит как фанера над Парижем.  :'(


Название: Re: Как сделать аттрибут собственного класса
Отправлено: Scotty от Ноябрь 02, 2009, 22:10
Хм ... нешто мыслей нет ? Или я чего опять ступил ?


Название: Re: Как сделать аттрибут собственного класса
Отправлено: Scotty от Ноябрь 03, 2009, 00:40
Пробовал сделать вроде синглетона (хранить один экземпляр на класс), но что то н е очень получилось - писал так:
Код
C++ (Qt)
class LogItem
{
public:
   LogItem(const QDomElement &aLogItem);
   ~LogItem();
   QString getFileName();
   QString getOwnerMoniker();
   QString getName();
   int getStatus();
   QString getMoniker();
   QString getTest();
   QString getPersistentDataKey();
   QString getProjectKey();
   QString getRelativeFileName();
   bool hasChildren();
   int getChildrenCount();
   LogItemChildren getChildren(int aChildrenindex);
   LogMessages * getLogMessages();
private:
   void setRelativePath(QString aPath);
protected:
   QDomElement gLogItem;
   QString gLogPath;
   LogMessages * gLogMessages;
friend class LogSuite;
friend class LogItemChildren;
};
 
А в реализации вот что:
Код
C++ (Qt)
LogMessages * LogItem::getLogMessages(){
   if (!gLogMessages){
       gLogMessages->openFile(this->gLogPath + "/" + this->getFileName());
       return gLogMessages;
   } else
       return gLogMessages;
}
 
LogItem::LogItem(const QDomElement &aLogItem):gLogItem(aLogItem){
   this->gLogMessages = new LogMessages;
}
 
LogItem::~LogItem(){
   delete gLogMessages;
}
 
В результате вылетает с ошибкой:
Сигнатура проблемы:
  Имя события проблемы:   APPCRASH
  Имя приложения:   Log_Test.exe
  Версия приложения:   0.0.0.0
  Отметка времени приложения:   4aef5171
  Имя модуля с ошибкой:   QtXmld4.dll
  Версия модуля с ошибкой:   4.5.2.0
  Отметка времени модуля с ошибкой:   4a3f7c18
  Код исключения:   c0000005
  Смещение исключения:   000060bf
  Версия ОС:   6.1.7600.2.0.0.256.1
  Код языка:   1049
  Дополнительные сведения 1:   0a9e
  Дополнительные сведения 2:   0a9e372d3b4ad19135b953a78882e789
  Дополнительные сведения 3:   0a9e
  Дополнительные сведения 4:   0a9e372d3b4ad19135b953a78882e789

Помогите пожалуйста убогому, сами мы не местные :)


Название: Re: Как сделать аттрибут собственного класса
Отправлено: Alex Custov от Ноябрь 03, 2009, 04:04
Код
C++ (Qt)
LogMessages * LogItem::getLogMessages(){
   if (!gLogMessages){
       gLogMessages->openFile(this->gLogPath + "/" + this->getFileName());
       return gLogMessages;
   } else
       return gLogMessages;
}
 

Бегло осмотрев код, нашёл вот это... Тут программа упадёт, разыменование нулевого указателя. Возможно ещё где-то, просмотри весь код.

Если ты сам уже не разбираешься в коде, перепиши всё с нуля, поэтапно.


Название: Re: Как сделать аттрибут собственного класса
Отправлено: Scotty от Ноябрь 03, 2009, 09:26
Мда ... я код видно уже не понимал, там точно валиться будет, щас попробую перекомпилировать, только НЕ убиру. Но вобще правилен ли подход, я не понимаю как это сделать ...