Russian Qt Forum
Ноябрь 24, 2024, 01:09 *
Добро пожаловать, Гость. Пожалуйста, войдите или зарегистрируйтесь.
Вам не пришло письмо с кодом активации?

Войти
 
  Начало   Форум  WIKI (Вики)FAQ Помощь Поиск Войти Регистрация  

Страниц: [1]   Вниз
  Печать  
Автор Тема: const - как лучше?  (Прочитано 4829 раз)
Igors
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 11445


Просмотр профиля
« : Декабрь 14, 2010, 20:46 »

Добрый день

Есть класс Texture и многие его методы const (не изменяют экземпляр). Но требуется отслеживать все созданные экземпляры. Я использую std::set (с тем же успехом можно QSet). Как мне его объявить: так

Код
C++ (Qt)
typedef std::set <Texture *> TextureSet;
 
Или так
Код
C++ (Qt)
typedef std::set <const Texture *> TextureSet;
 

В первом случае мне надо приводить const_cast всякий раз когда я добавляю/удаляю в/из set в константном методе (немало). Во втором всякий раз когда я итерирую TextureSet (меньше но тоже много).

Или есть лучшее решение чтобы избежать множества приведений?

Спасибо
Записан
whirlwind
Гость
« Ответ #1 : Декабрь 14, 2010, 21:24 »

можно сделать это поле mutable, тогда его можно будет менять из const методов
Записан
pastor
Administrator
Джедай : наставник для всех
*****
Offline Offline

Сообщений: 2901



Просмотр профиля WWW
« Ответ #2 : Декабрь 14, 2010, 21:35 »

Непонятно, чем не устраивает первый способ хранения:

Цитировать
typedef std::set <Texture *> TextureSet;

Какие операции предполагается выполнять с объектами Texture? Вызывать его константные методы? Так способ храния здесь непричем. Если методы константные, то они не должены менять состояние объета, в противном случае: убираем "const" или ищем ошибку в проектировании класса.


При втором способе хранение весь объект константный. Нельзя менять его состояние, даже если он не содержит константных методов.


Записан

Integrated Computer Solutions, Inc. (ICS)
http://www.ics.com/
Igors
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 11445


Просмотр профиля
« Ответ #3 : Декабрь 14, 2010, 22:09 »

Непонятно, чем не устраивает первый способ хранения:

Цитировать
typedef std::set <Texture *> TextureSet;
Многим, напр нельзя так

Код
C++ (Qt)
// проверяем такая текстура уже есть в глобальном set
static bool LookupTexture( const Texture * iTexture )
{
return theTextures.find(iTexture) != theTextures.end();
}
 
Если здесь убрать const - это потянет за собой др. методы.

Какие операции предполагается выполнять с объектами Texture? Вызывать его константные методы? Так способ храния здесь непричем. Если методы константные, то они не должены менять состояние объета, в противном случае: убираем "const" или ищем ошибку в проектировании класса.

При втором способе хранение весь объект константный. Нельзя менять его состояние, даже если он не содержит константных методов.
По книжке - да, а по жизни как?  Улыбающийся Вот пример

Код
C++ (Qt)
if (!LookupTexture(iTexture))  {    // текстура  готова?
theTextures.insert(iTexture);       // нет, регистрируем ее
iTexture->CreateDataOpenGL();   // это не константный метод
|
 

можно сделать это поле mutable, тогда его можно будет менять из const методов
Полей тех много и они в очень многих др.  классах
« Последнее редактирование: Декабрь 14, 2010, 22:12 от Igors » Записан
pastor
Administrator
Джедай : наставник для всех
*****
Offline Offline

Сообщений: 2901



Просмотр профиля WWW
« Ответ #4 : Декабрь 15, 2010, 00:02 »

Цитировать
Многим, напр нельзя так
Цитировать
Если здесь убрать const - это потянет за собой др. методы.

Что потянет? Какие методы?


Цитировать
Вот пример

Что не так с примером?

Код
C++ (Qt)
std::set <Texture *> theTextures;
 
Texture *iTexture = new Texture();
 
if (!LookupTexture(iTexture)) {
   theTextures.insert(iTexture);
   iTexture->CreateDataOpenGL();
}

В чем проблема то?
Записан

Integrated Computer Solutions, Inc. (ICS)
http://www.ics.com/
twp
Гость
« Ответ #5 : Декабрь 15, 2010, 12:40 »

Цитировать
Цитировать
typedef std::set <Texture *> TextureSet;
Многим, напр нельзя так

Код
C++ (Qt)
static bool LookupTexture( const Texture * iTexture )
{
return theTextures.find(iTexture) != theTextures.end();
}
 
Если здесь убрать const - это потянет за собой др. методы.
Все верно, метод find не может автоматически привести const Texture * в Texture *.
В данном случае можно попробовать обявить так:
typedef std::set<Texture const *> TextureSet;
Хотя это может затронуть другие части кода в приложении.
Записан
pastor
Administrator
Джедай : наставник для всех
*****
Offline Offline

Сообщений: 2901



Просмотр профиля WWW
« Ответ #6 : Декабрь 15, 2010, 15:21 »

Цитировать
Все верно, метод find не может автоматически привести const Texture * в Texture *.

Тут имеет место попытка приведения к Texture *const &, которое неможет быть выполнено. Это весьма очевидно если посомтреть как объявлен метод find для std::set или QSet


iterator find ( const key_type& x ) const;

iterator QSet::find ( const T & value );
« Последнее редактирование: Декабрь 15, 2010, 15:28 от pastor » Записан

Integrated Computer Solutions, Inc. (ICS)
http://www.ics.com/
twp
Гость
« Ответ #7 : Декабрь 15, 2010, 15:42 »

Цитировать
Все верно, метод find не может автоматически привести const Texture * в Texture *.

Тут имеет место попытка приведения к Texture *const &, которое неможет быть выполнено. Это весьма очевидно если посомтреть как объявлен метод find для std::set или QSet


iterator find ( const key_type& x ) const;

iterator QSet::find ( const T & value );
Может и так но gcc не согласен:
error: invalid conversion from 'const Texture*' to 'Texture*'

Записан
Igors
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 11445


Просмотр профиля
« Ответ #8 : Декабрь 15, 2010, 17:41 »

Что не так с примером?

Код
C++ (Qt)
std::set <Texture *> theTextures;
 
Texture *iTexture = new Texture();
 
if (!LookupTexture(iTexture)) {
   theTextures.insert(iTexture);
   iTexture->CreateDataOpenGL();
}

В чем проблема то?
В том что такие методы/ф-ции как LookupTexture очень часто нужны в константных методах
Записан
Страниц: [1]   Вверх
  Печать  
 
Перейти в:  


Страница сгенерирована за 0.215 секунд. Запросов: 23.