Форум программистов, компьютерный форум, киберфорум
Наши страницы

С++ для начинающих

Войти
Регистрация
Восстановить пароль
 
 
Рейтинг: Рейтинг темы: голосов - 11, средняя оценка - 4.73
Buckstabue
175 / 124 / 6
Регистрация: 12.01.2012
Сообщений: 624
#1

Как инициализровать константное поле класса в конструкторе? - C++

09.08.2012, 01:53. Просмотров 1519. Ответов 22
Метки нет (Все метки)

Здравствуйте. Такая проблема. Класс работает с множеством картинок одинакового разрешения. Размеры картинки должны храниться в полях класса(естественно лучше константных). Такая проблема: инициализировать константы в моём случае можно только через конструктор до тела констутора; чтобы узнать размер картинки надо создавать объект любой картинки из коллекции и методами width(), height() получать необходимые данные, при этом сама картинка не является полем класса. Требуется инициализировать мои поля внутри конструтора
Как это сделать наиболее красиво и элегантно, без костылей, и чтобы класс выглядел максимально независимым модулем?
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
Similar
Эксперт
41792 / 34177 / 6122
Регистрация: 12.04.2006
Сообщений: 57,940
09.08.2012, 01:53
Здравствуйте! Я подобрал для вас темы с ответами на вопрос Как инициализровать константное поле класса в конструкторе? (C++):

Константное поле класса как размер массива - C++
class Array { private: const int size; int array; public: Array(): size(10) { }

Только константное статическое поле НЕ МОЖЕТ быть поле членом класса ! - C++
class CCoords { static const float rate = 1.0f; // ОШИБКА !!! bool IsComputed; float x,y; POINT2D ...

Друзья, подскажите, как в классе создать константное поле, ссылочное поле и объектное поле? - C++
Препод на защите лабораторной по классам дал задание большое. В общем-то все пункты я знаю как делать, кроме этого. Вот что такое...

В конструкторе вложенного класса инициализируется приватное поле. Потом вызывается функция-метод этого класса и выводит значение этого поля НО НЕ ТО! - C++
Друзья! Почему так? #include <windows.h> #include <iostream> using namespace std; //Вот главный класс class A{ ...

Мое константное статическое поле только что было использовано до того как оно создалось? - C++
В названии темы уже понятно, думаю, что у меня за проблема. Я экспериментировал со статическими полями классов (в частности с...

Как вызвать виртуальную функцию из дочернего класса, если она определена и вызывается в конструкторе РОДИТЕЛЬСКОГО класса? - C++
Ну то есть так: есть родительский и дочерний класс, в родительском определен виртуальная функция и вызывается в его конструкторе (камень...

22
Buckstabue
175 / 124 / 6
Регистрация: 12.01.2012
Сообщений: 624
10.08.2012, 04:26  [ТС] #16
Цитата Сообщение от novi4ok Посмотреть сообщение
картинка всегда под рукой со своими методами width() & height(). зачем дублировать то, что уже есть?
Вначале я именно так и делал, до тех пор пока не пришлось обрабатывать событие mouseMove т.е. любое перемещение мыши должно было бы либо каждый раз вызывать одни и те же функции img.width() и img.height() в то время, когда эти возвращаемые значения за время работы программы не изменяются. Мне стал этого жалко, вот и создал тему

Добавлено через 3 минуты
yuron_477, юрон, вы имеете в виду инициализвация константых полей в объявлении класса? Странно, у меня такой код ещё год назад работал на gcc не самых последних версий. И вообще такой способ инициализации есть по-моему даже в книге Дейтелов 2007 года издания
0
Nameless One
Эксперт С++
5777 / 3427 / 255
Регистрация: 08.02.2010
Сообщений: 7,448
10.08.2012, 06:00 #17
Цитата Сообщение от ValeryS Посмотреть сообщение
StasGamilton,
здесь ключевое
Такая проблема: инициализировать константы в моём случае можно только через конструктор до тела констутора;
что у тебя и написано
C++
1
A(int _a) : a(_a) {}
Так инициализация в списке инициализации и происходит до тела конструктора
0
Nameless One
Эксперт С++
5777 / 3427 / 255
Регистрация: 08.02.2010
Сообщений: 7,448
10.08.2012, 06:22 #18
Цитата Сообщение от Buckstabue Посмотреть сообщение
В идеале хотелось бы что-то вроде этого
Запросто:

C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
#include <iostream>
#include <string>
#include <cstdlib>
#include <ctime>
 
class image
{
    std::string name;
    size_t width, height;
    
public:
    image(const std::string& n)
        : name(n), width(rand() % 10 + 1), height(rand() % 10 + 1)
    {
    }
 
    size_t get_width() const
    {
        return width;
    }
 
    size_t get_height() const
    {
        return height;
    }
 
    std::string get_name() const
    {
        return name;
    }
};
 
class image_processor
{
    image img;
    const size_t img_width, img_height;
 
public:
    image_processor(const image& image)
        : img(image), img_width(img.get_width()), img_height(img.get_height())
    {
    }
 
    void run() const
    {
        std::cout << "Processing image `" << img.get_name() << "' "
                  << img_width << "x" << img_height << std::endl;
    }
};
 
int main()
{
    srand(time(NULL));
    
    image_processor(image("facepalm.jpg")).run();
}
Цитата Сообщение от Buckstabue Посмотреть сообщение
И вообще такой способ инициализации есть по-моему даже в книге Дейтелов 2007 года издания
а вот это вряд ли. Если верить этой страничке, то такое есть только в последних версиях GCC и Clang
0
Buckstabue
175 / 124 / 6
Регистрация: 12.01.2012
Сообщений: 624
10.08.2012, 06:28  [ТС] #19
Nameless One, я же просил не только рабочий пример, но и элегантный а по мне так лучше хранить в поле класса костантную структуру типа этого
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
#include <imagelib>
 
struct Rect
{
      int width;
      int height;
      Rect(char * str)
      {
         Image img(str);
         width = img.width();
         height = img.height();
      }
};
 
class MyClass
{
      MyClass()
         : rect("/images/01.png")
      {
         cout << rect.width << rect.height;
      }
      const Rect rect;
 
};
Но в любом случае, я решил не делать эти переменные константными, а просто внимательно слежу где что меняется, единственное что убивает, эти переменные очень часто применяются и если надо будет приступить к доработке через месяц, то и не вспомню, что её менять не следует
0
Nameless One
Эксперт С++
5777 / 3427 / 255
Регистрация: 08.02.2010
Сообщений: 7,448
10.08.2012, 06:33 #20
Цитата Сообщение от Buckstabue Посмотреть сообщение
Nameless One, я же просил не только рабочий пример, но и элегантный а по мне так лучше хранить в поле класса костантную структуру типа этого
тебе шашечки или ехать? Чтобы говорить об "элегантности", нужно сперва четко представлять, что именно и как должен делать код. Представлять общую картину, так сказать. Кроме тебя, наверное, никто в этой теме это не может сделать, т.к. автор - ты. А я всего лишь довел тобой же приведенный пример до рабочего состояния (с незначительными изменениями)
1
Buckstabue
175 / 124 / 6
Регистрация: 12.01.2012
Сообщений: 624
10.08.2012, 06:42  [ТС] #21
Мне просто не нравится когда в полях класса есть вспомогательные переменные, хотя чего я так о памяти пекусь... тем более картиночки в среднем небольшие по разрешению и вряд ли прям вся информация сразу загружается в память при загрузке картинки..
0
PointsEqual
ниначмуроФ
836 / 520 / 33
Регистрация: 12.10.2009
Сообщений: 1,915
10.08.2012, 09:09 #22
Цитата Сообщение от Buckstabue Посмотреть сообщение
инициализировать константы в моём случае можно только через конструктор до тела констутора;
можно сделать маленький хак с помощью const_cast:
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
class cTest
{
public:
    cTest(): x(7), y(11)
    {
        ChangeX(333);
    }
 
    int GetX() const
    {
        return cTest::x;
    }
 
 
private:
    void ChangeX(int newVal)
    {
        const int* tmp = &x;
        int* j = const_cast<int*>(tmp);
        *j = newVal;
    }
 
 
 
private:
    const int x;
    const int y;
 
};
 
///////////////////////////////////////////////
 
int main()
{
    cTest ob;
    cout << ob.GetX();
 
 
    return 0;
}
0
Buckstabue
175 / 124 / 6
Регистрация: 12.01.2012
Сообщений: 624
10.08.2012, 09:31  [ТС] #23
Хм. Я читал, что на многих системах константы помещаются в защищенную от записи область памяти и попытка изменить константу приводит к runtime_error. А у const_cast немногое другое применение - он нужен только для передачи константных данных в функцию, которая не имеет в прототипе указания const, и вся ответственность за ошибки будет лежать на программисте, если эту константу функция попытается изменить. Лучше этого не делать, хотя задумывался над этим
0
10.08.2012, 09:31
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
10.08.2012, 09:31
Привет! Вот еще темы с ответами:

Работа со строчками (как задать поле в конструкторе?) - C++
Здравствуйте, сразу к коду class Shape { private: public: char name; virtual int GetVolume()=0; };...

Как задать размер матрицы в конструкторе класса? - C++
Подскажите как задать размер матрицы в конструкторе класса? Решаю задачи из учебника, не могу понять, думаю это невозможно... Р. Лафоре...

Как проинициализировать структурную переменную в конструкторе класса? - C++
К примеру у меня есть переменная p типа POINT. Такую запись он считает нелегальной: private: POINT p; public: MyClass()...

Как в конструкторе класса передать параметром указатель на функцию? - C++
Друзья! Вот тут всё понятно, есть класс, в котором приватная функция f_0, в конструкторе передаётся указатель на функцию f_1. Эта функция...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
23
Ответ Создать тему
Опции темы

КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin® Version 3.8.9
Copyright ©2000 - 2017, vBulletin Solutions, Inc.