Russian Qt Forum

Программирование => С/C++ => Тема начата: Igors от Декабрь 14, 2010, 20:46



Название: const - как лучше?
Отправлено: Igors от Декабрь 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 (меньше но тоже много).

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

Спасибо


Название: Re: const - как лучше?
Отправлено: whirlwind от Декабрь 14, 2010, 21:24
можно сделать это поле mutable, тогда его можно будет менять из const методов


Название: Re: const - как лучше?
Отправлено: pastor от Декабрь 14, 2010, 21:35
Непонятно, чем не устраивает первый способ хранения:

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

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


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




Название: Re: const - как лучше?
Отправлено: Igors от Декабрь 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 методов
Полей тех много и они в очень многих др.  классах


Название: Re: const - как лучше?
Отправлено: pastor от Декабрь 15, 2010, 00:02
Цитировать
Многим, напр нельзя так
Цитировать
Если здесь убрать const - это потянет за собой др. методы.

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


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

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

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

В чем проблема то?


Название: Re: const - как лучше?
Отправлено: twp от Декабрь 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;
Хотя это может затронуть другие части кода в приложении.


Название: Re: const - как лучше?
Отправлено: pastor от Декабрь 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 );


Название: Re: const - как лучше?
Отправлено: twp от Декабрь 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*'



Название: Re: const - как лучше?
Отправлено: Igors от Декабрь 15, 2010, 17:41
Что не так с примером?

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

В чем проблема то?
В том что такие методы/ф-ции как LookupTexture очень часто нужны в константных методах