LINUX.ORG.RU

Странная ошибка с const

 ,


0

1

Не хочет компилироваться следующий метод:

// Преобразование таблицы конечных записей в Dom документ
QDomElement RecordTableData::exportDataToDom(QDomDocument *doc) const
{
  // Если у ветки нет таблицы конечных записей, возвращается пустой документ
  if(tableData.size()==0)
    return QDomElement();

  QDomElement recordTableDomData=doc->createElement("recordtable");

  // Пробегаются все записи в таблице
  for(int i=0; i<tableData.size(); i++)
    recordTableDomData.appendChild( tableData.at(i).exportDataToDom( doc ) ); // К элементу recordtabledata прикрепляются конечные записи

  // qDebug() << "In export_modeldata_to_dom() recordtabledata " << doc.toString();

  return recordTableDomData;
}


Ошибка выглядит так:

src\models\recordTable\RecordTableData.cpp: In member function 'QDomElement RecordTableData::exportDataToDom(QDomDocument*) const':
src\models\recordTable\RecordTableData.cpp:308:74: error: passing 'const Record' as 'this' argument of 'QDomElement Record::exportDataToDom(QDomDocument*)' discards qualifiers [-fpermissive]
     recordTableDomData.appendChild( tableData.at(i).exportDataToDom( doc ) ); // К элементу recordtabledata прикрепляются конечные записи


Не пойму чего хочет компилер. Сначала думал, что проблема в том, что метод константный, и вызывает неконстантный метод

tableData.at(i).exportDataToDom( doc )

Но потом понял, что вызываемый неконстантный метод - это метод другого класса, так что он влиять не может.

И так же убирание const из определения вышеприведенного метода проблему не решает.

Вопрос: как заставить компилироваться код?

Исходники: https://github.com/xintrea/mytetra_dev/commits/experimental
Коммит: 3c674e61423616ae3ca8e4191c09cfaed945a8ef

★★★★★

внезапно: tableData.at(i) возвращает const Record &

dt1 ★★
()

Во-первых метод at возвращает константную ссылку. Вот он на это и ругается в первую очередь.

Во-вторых, тут recordTableDomData.appendChild ты вроде пытаешься поменять поле класса?

grondek
()

Вот эта хрень - exportDataToDom( doc ) не константная
А вот эта -tableData.at(i) наоборот, константная, потому как at(i) возвращает константную ссылку.

AF ★★★
()
Ответ на: комментарий от AF

Ну я для интереса заменил at(i) на [ i ]:

recordTableDomData.appendChild( tableData[i].exportDataToDom( doc ) );


но ошибка осталась:

recordTableDomData.appendChild( tableData[i].exportDataToDom( doc ) );

../mytetra/src/models/recordTable/RecordTableData.cpp: In member function 'QDomElement RecordTableData::exportDataToDom(QDomDocument*) const':
../mytetra/src/models/recordTable/RecordTableData.cpp:308:71: error: passing 'const Record' as 'this' argument of 'QDomElement Record::exportDataToDom(QDomDocument*)' discards qualifiers [-fpermissive]
     recordTableDomData.appendChild( tableData[i].exportDataToDom( doc ) ); // К элементу recordtabledata прикрепляются конечные записи


https://github.com/xintrea/mytetra_dev/commit/bdb2f926dcf18bbf2ba33720bf1b613...

Xintrea ★★★★★
() автор топика
Ответ на: комментарий от Xintrea

друже, тебе глаголят, что метод exportDataToDom не константный, однако, сучилось так, что tableData есть константа, поскольку находится в константном методе класса. Для константы возбранятеся вызывать не константный метод. Либо метод на неконстентный, сиречь убери «const», либо соизволь сделать tableData mutable. В общем в консерватории что-то не так.

anonymous
()
Ответ на: комментарий от anonymous

сиречь убери «const»

Блин я столько с ними мучался чтоб расставить.


либо соизволь сделать tableData mutable

А это что имеешь в виду?

Xintrea ★★★★★
() автор топика
Ответ на: комментарий от Xintrea
    // Таблица записей (в нормальном виде содержит только "легкие" объекты записей)
    QList< Record > tableData;

-->

    // Таблица записей (в нормальном виде содержит только "легкие" объекты записей)
    mutable QList< Record > tableData;

но это коряво. Убери лучше конст, если ты меняешь объект.

anonymous
()
Ответ на: комментарий от Xintrea

Ну я для интереса заменил at(i) на [ i ]:

Ты забыл, шо:
1) T & QList::operator[](int i)
2) const T & QList::operator[](int i) const

В твоем случае компилятор выбрал второй вариант, потому, как QDomElement RecordTableData::exportDataToDom(QDomDocument *doc) const

AF ★★★
()
Ответ на: комментарий от Xintrea

самое забавное, что у тебя явно константные методы НЕКОНСТАНТНЫ! пример:

// Получение значения текста указанной записи
// Метод возвращает расшифрованные данные
// Если возникнет проблема, что файла с текстом записи нет, будет создан пустой файл
QString RecordTableData::getText(int pos)
{
 // Если индекс недопустимый, возвращается пустая строка
 if(pos<0 || pos>=size()) 
   return QString();

 return tableData[pos].getTextDirect();
}

anonymous
()
Ответ на: комментарий от Xintrea

сиречь убери «const»

Как только я его убираю, у меня по цепочке приходится убирать консты со всех геттеров. А это нехорошо.

Проблема возникла из-за того, что я в топиковом геттере решил сделать кеширование. И записываю возвращаемое значение в поле класса. Из-за этого, топиковый геттер не может быть константным, и пошло и поехало.

Не знаю как это обойти.

Xintrea ★★★★★
() автор топика
Ответ на: комментарий от Xintrea

так на кого дьявола у тебя геттер меняет объект? Геттер - получение. Не должен он ничего менять.

anonymous
()
Ответ на: комментарий от Xintrea

Проблема возникла из-за того, что я в топиковом геттере решил сделать кеширование. И записываю возвращаемое значение в поле класса.

Почитай про ключевое слово mutable.

anonymous
()
Ответ на: комментарий от anonymous

так на кого дьявола у тебя геттер меняет объект? Геттер - получение. Не должен он ничего менять.

Вполне может, как раз в случае кэширования/ленивого чтения. И такие поля просто имеют спецификатор mutable.

anonymous
()
Ответ на: комментарий от anonymous

самое забавное, что у тебя явно константные методы НЕКОНСТАНТНЫ!

Я знаю об этом. В данном месте должен быть конст, тут надо подправить. Но у меня данные хранятся как в памяти, так и на диске (т. н. «легкие» данные - в памяти, а «тяжелые» - на диске). И я пока не могу сообразить, как с ними обращаться с точки зрения конста. С данными в памяти все понятно. А вот с данными на диске - нет, потому что они не хранятся в свойствах класса.

Xintrea ★★★★★
() автор топика
Ответ на: комментарий от anonymous

Вполне может, как раз в случае кэширования/ленивого чтения

тогда вполне mutable член класса нужен тут.

anonymous
()
Ответ на: комментарий от hobbit

range for использовать религия не позволяет?

починено

anonymous
()
Ответ на: комментарий от hobbit

там свой, уникальный форич, чуть ли не на макросах. таких велосипедов — полно.

next_time ★★★★★
()
Ответ на: комментарий от anonymous

Главное в геттерах - идемпотентность при условии неизменения объекта снаружи. А как он там внутри работает - начихать.

cdshines ★★★★★
()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.