Форум программистов, компьютерный форум, киберфорум
С++ для начинающих
Войти
Регистрация
Восстановить пароль
Блоги Сообщество Поиск Заказать работу  
 
Рейтинг 4.81/26: Рейтинг темы: голосов - 26, средняя оценка - 4.81
0 / 0 / 0
Регистрация: 08.06.2009
Сообщений: 4

Как правильно инициализировать статические члены класса?

07.07.2009, 04:10. Показов 5590. Ответов 10
Метки нет (Все метки)

Студворк — интернет-сервис помощи студентам
Я новичок и заранее прошу прощение за тупые вопросы. Имеются два класса: Solution и Pool. Pool состоит из нескольких обьектов класса Solution. Эти обьекты отличаются только переменными *x и y. Все остальные члены одинаковы: **a, n, yFunc. Чтобы предотвратить копирование **a и n во все обьекты Solution, я обьявил их как static. Вопрос такой: правильно ли я инициализирую **a и n внутри конструктора Pool? Может имеется другой, более элегантный способ глобального использования **a и n во всех обьектах Solution. Как мне поступить с функцией yFunc, которая тоже общая для всех обьектов Solution? Заранее спасибо!

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
class Solution
{
    double *x;
    double y;
    static double **a; // общие для всех обьектов класса
    static int n; // общий для всех обьектов класса
public:
    static void StaticSet(int,double**)
    Solution();
    ~Solution();
    double yFunc(); // хотелось бы иметь одну версию этой функции для всех обьектов данного класса
}
 
Solution::StaticSet(int numx,double **coef)
{
    n=numX;
    a = new double*[2];
    for(int i=0;i<2;i++) a[i] = new double[n];
    for(int i=0;i<2;i++) 
        for(int j=0;j<n;j++)
            a[i][j] = coef[i][j];
}
 
Solution::Solution()
{
    srand(time(0));
    for(int j=0;j<n;j++)
        x[j] = 2.0*(rand()/(double)RAND_MAX-0.5);
}
 
Pool::Pool(int numSols, int numX, double **coef)
{
    poolSize = numSols;
    Solution::StaticSet(numX,coef); // правильно ли это?
    for(int i=0;i<poolSize;i++)
        sols.push_back(new Solution());
}
0
cpp_developer
Эксперт
20123 / 5690 / 1417
Регистрация: 09.04.2010
Сообщений: 22,546
Блог
07.07.2009, 04:10
Ответы с готовыми решениями:

Как инициализировать статические члены класса
Помогите пожалуйста....я не знаю как вывести в статическое поле значения((( #include &lt;conio.h&gt; #include &lt;stdlib.h&gt; ...

Как инициализировать члены класса, являющегося параметром шаблона
#include &lt;iostream&gt; #include &lt;conio.h&gt; using namespace std; template &lt;typename SomeClass&gt; class Array { private : ...

Как правильно инициализировать данные-члены строкового типа в реализации функции-члена?
Всем здравствуйте. У меня тут возникла очень глупая ошибка и я не могу понять в чем причина и как ее исправить. Значит, имеется структура. ...

10
Любитель давать советы
 Аватар для Alexiski
342 / 135 / 14
Регистрация: 12.01.2009
Сообщений: 511
07.07.2009, 05:19
Цитата Сообщение от Влад1966 Посмотреть сообщение
Вопрос такой: правильно ли я инициализирую **a и n внутри конструктора Pool? Может имеется другой, более элегантный способ глобального использования **a и n во всех обьектах Solution.
Со статикой, вроде правильно, а вот нестатический *x в конструкторе надо обязательно разместить перед заполнением. И еще хорогий тон - все, что создается в конструторе, обязательно уничтожать в деструкторе.

Цитата Сообщение от Влад1966 Посмотреть сообщение
Как мне поступить с функцией yFunc, которая тоже общая для всех обьектов Solution?
Функции, которые члены класса, и так общие для всех объектов.
Тут главный вопрос другой: должна ли эта функция работать с полями x и y конкретного класса? Если не должна, то ее можно сделать статической. Если должна, то ее делать статической нельзя.

И хотя нестатическая функция вызывается через конкретный объект, это не значит, что она своя у каждого объекта. Фактически, этот объект просто передается ей как скрытый параметр.
1
0 / 0 / 0
Регистрация: 08.06.2009
Сообщений: 4
07.07.2009, 07:25  [ТС]
Большое спасибо. Забыл я про память для *x. Функция yFunc работает с статическими и нестатическими параметрами. Как я правильно Вас понял, её нельзя делать статической.
0
Evg
Эксперт CАвтор FAQ
 Аватар для Evg
21281 / 8305 / 637
Регистрация: 30.03.2009
Сообщений: 22,660
Записей в блоге: 30
07.07.2009, 09:10
> Pool состоит из нескольких обьектов класса Solution

При этом я вижу только один вызов StaticSet В конструкторе

А вообще код на самом деле написан неверно. При появлении нового объекта класса Pool будет вызываться конструктор Pool, который вызовет StaticSet, а там массив a выделится по-новой.

Правильно писать что-то типа того:

C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
class Solution
{
  ...
  static double **a = NULL ; // <------ статически инициализируем NULL'ом
  ...
}
 
Solution::StaticSet(int numx,double **coef)
{
  ...
  if (a != NULL)  // <-------- чтобы при повторном заходе в этот метод не перевыделять память
  {
    a = new double*[2];
    ...
  }
  ...
}
Здесь я просто на пальцах пояснил суть ошибки и как она лечится. В данном случае это скорее затычка нежели концептуально правильное исправление. Не видя описания классов целиком и пояснений, что же это такое, не могу сказать, как это делать правильно
0
0 / 0 / 0
Регистрация: 08.06.2009
Сообщений: 4
07.07.2009, 20:00  [ТС]
Спасибо Evg. Я тут порылся в книгах и на инете и нашёл ещё один вариант обьявления общих членов класса без их копирования для всех обьектов этого класса.
Итак, вариант №1 - статические члены
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
class Solution
{
    double *x;
    double y;
    static double **a = NULL;
    static int n;
public:
    static void StaticSet(int,double**)
    Solution();
    ~Solution();
    double yFunc();
}
 
void Solution::StaticSet(int numx,double **coef)
{
    n=numX;
    if(a!=NULL)
    {
        a = new double*[2];
        for(int i=0;i<2;i++) a[i] = new double[n];
        for(int i=0;i<2;i++) 
            for(int j=0;j<n;j++)
                a[i][j] = coef[i][j];
    }
}
 
Solution::Solution()
{
    x = new double[n];
    srand(time(0));
    for(int j=0;j<n;j++)
        x[j] = 2.0*(rand()/(double)RAND_MAX-0.5);
}
 
Pool::Pool(int numSols, int numX, double **coef)
{
    poolSize = numSols;
    Solution::StaticSet(numX,coef);
    for(int i=0;i<poolSize;i++)
        sols.push_back(new Solution());
}
Вариант №2 - отдельный класс-ссылка
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
57
class Statics
{
public:
    double **a;
    int n;
    Statics(int,double **);
    ~Statics();
};
 
class Solution
{
    double *x;
    double y;
    Statics *t
public:
    Solution(Statics *t);
    ~Solution();
    double yFunc();
}
 
Statics::Statics(int numX,double **coef)
{
    n=numX;
    a = new double*[2];
    for(int i=0;i<2;i++) a[i] = new double[n];
    for(int i=0;i<2;i++) 
        for(int j=0;j<n;j++)
                a[i][j] = coef[i][j];
}
 
Solution::Solution(Statics *in_t)
{
    t=in_t;
    srand(time(0));
    for(int j=0;j<t->n;j++)
        x[j] = 2.0*(rand()/(double)RAND_MAX-0.5);
}
 
class Pool
{
    vector<Solution> sols;
    int poolSize;
public:
    Pool(int,int,double*);
    ~Pool();
}
 
Pool::Pool(int numSols, int numX, double **coef)
{
    poolSize = numSols;
    Statics stat(numX,coef);
    for(int i=0;i<poolSize;i++)
    {
        Solution sol = new Solution (&stat);
        sols.push_back(sol);
    }
}
Какой вариант имеет больше преимуществ?
0
Maniac
Эксперт С++
 Аватар для ISergey
1464 / 965 / 160
Регистрация: 02.01.2009
Сообщений: 2,820
Записей в блоге: 1
07.07.2009, 20:11
Цитата Сообщение от Evg Посмотреть сообщение
C++
1
2
3
4
5
6
class Solution
{
 ...
 static double **a = NULL ; // <------ статически инициализируем NULL'ом
 ...
}
Вообще так надо
C++
1
2
3
4
5
6
7
class Solution
{
 ...
 static double **a; // = NULL ; // <------ статически инициализируем NULL'ом
 ...
}
double** Solution::а = NULL; // <------ статически инициализируем
0
Evg
Эксперт CАвтор FAQ
 Аватар для Evg
21281 / 8305 / 637
Регистрация: 30.03.2009
Сообщений: 22,660
Записей в блоге: 30
07.07.2009, 20:21
Цитата Сообщение от Влад1966 Посмотреть сообщение
Какой вариант имеет больше преимуществ?
Я уже писал, чтобы понять, как идеологически делать правильно, надо понять, а что ты делать будешь.

Цитата Сообщение от ISergey Посмотреть сообщение
Вообще так надо
Можно и так, но Си++ разрешает статическую инициализацию внутри класса для integral типов (т.е. целые и поинтеры). А вот плавающие уже так инициализировать нельзя. Удобнее это делать внутри класса, тогда сразу видно что к чему
0
Maniac
Эксперт С++
 Аватар для ISergey
1464 / 965 / 160
Регистрация: 02.01.2009
Сообщений: 2,820
Записей в блоге: 1
07.07.2009, 20:27
Можно и так, но Си++ разрешает статическую инициализацию внутри класса для integral типов (т.е. целые и поинтеры). А вот плавающие уже так инициализировать нельзя. Удобнее это делать внутри класса, тогда сразу видно что к чему
C++
1
2
3
4
5
6
7
8
9
10
11
class Employee{
    static int **x = 0;
public:
};
 
//int **Employee::x = 0;
 
int main()
{
    return 0;
}
1>------ Build started: Project: testing, Configuration: Debug Win32 ------
1>Compiling...
1>main.cpp
1>d:\progcode\c++\projforum\testing\main .cpp(5) : error C2864: 'Employee::x' : only static const integral data members can be initialized within a class
1>Build log was saved at "file://d:\ProgCode\C++\ProjForum\testing\Debug\ BuildLog.htm"
1>testing - 1 error(s), 0 warning(s)
========== Build: 0 succeeded, 1 failed, 0 up-to-date, 0 skipped ==========
0
Evg
Эксперт CАвтор FAQ
 Аватар для Evg
21281 / 8305 / 637
Регистрация: 30.03.2009
Сообщений: 22,660
Записей в блоге: 30
07.07.2009, 20:42
Ах ты ёлки зелёные, это ж только для const'ов так можно. ТОгда да, отдельной строкой
0
0 / 0 / 0
Регистрация: 08.06.2009
Сообщений: 4
07.07.2009, 21:18  [ТС]
Значит первый вариант не годится? Статические данные иницилизируются внутри класса, что запрещено если они не const. Как насчёт второго варианта с классом-ссылкой. Будет ли копироваться класс Statics для каждого обьекта класса Solution или нет? Мне нужна только одна версия Statics для 100 обьектов класса Solution.

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
57
class Statics
{
public:
    double **a;
    int n;
    Statics(int,double **);
    ~Statics();
};
 
class Solution
{
    double *x;
    double y;
    Statics *t
public:
    Solution(Statics *t);
    ~Solution();
    double yFunc();
}
 
Statics::Statics(int numX,double **coef)
{
    n=numX;
    a = new double*[2];
    for(int i=0;i<2;i++) a[i] = new double[n];
    for(int i=0;i<2;i++) 
        for(int j=0;j<n;j++)
                a[i][j] = coef[i][j];
}
 
Solution::Solution(Statics *in_t)
{
    t=in_t;
    srand(time(0));
    for(int j=0;j<t->n;j++)
        x[j] = 2.0*(rand()/(double)RAND_MAX-0.5);
}
 
class Pool
{
    vector<Solution> sols;
    int poolSize;
public:
    Pool(int,int,double*);
    ~Pool();
}
 
Pool::Pool(int numSols, int numX, double **coef)
{
    poolSize = numSols;
    Statics stat(numX,coef);
    for(int i=0;i<poolSize;i++)
    {
        Solution sol = new Solution (&stat);
        sols.push_back(sol);
    }
}
0
Evg
Эксперт CАвтор FAQ
 Аватар для Evg
21281 / 8305 / 637
Регистрация: 30.03.2009
Сообщений: 22,660
Записей в блоге: 30
07.07.2009, 21:53
Цитата Сообщение от Влад1966 Посмотреть сообщение
Значит первый вариант не годится? Статические данные иницилизируются внутри класса, что запрещено если они не const.
Годится, только его немного подправить надо. ISergey в посте 6 написал как

Цитата Сообщение от Влад1966 Посмотреть сообщение
Как насчёт второго варианта с классом-ссылкой. Будет ли копироваться класс Statics для каждого обьекта класса Solution или нет? Мне нужна только одна версия Statics для 100 обьектов класса Solution.
Второй вариант плох тем, что он будет работать только в том случае, если будет создан только один экземпляр класса Pool. Т.е. на самом деле второй вариант плохой. Да и без поллитры не сразу поймёшь, в чём дело

Первый вариант нужно будет дорабатывать на тот случай, если у класса Statics будет несколько конструкторов. В этом случае для концептуальной правильности код по выделению памяти для a надо вынести в отдельный private метод и из каждого конструктора этот метод дёргать
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
raxper
Эксперт
30234 / 6612 / 1498
Регистрация: 28.12.2010
Сообщений: 21,154
Блог
07.07.2009, 21:53
Помогаю со студенческими работами здесь

Статические члены класса
Добрый день. Проходили тему - статические члены класса. Написали программу, вылезает ошибка, помогите побороть пожалуйста. #include...

Статические члены класса
Доброго времени суток. Задача состоит в том, чтобы создать список обыектов класса Test, с возможностью последующего добавления элементов...

Статические массивы, члены класса
необходимо создать статический массив. компилятор gcc #include&lt;iostream&gt; class c{ public: static const char x =...

Где инициализировать члены класса CTreeCtrl?
В диалоговом окне, например, оконные члены класса инициализируются в OnInitDialog(). Мне нужно получить буквы всех дисков, которые уже...

Конструктор класса, содержащего только статические члены
Практикуюсь по книге Стенли Липпмана &quot;Язык программирования C++ вводный курс&quot; 4 изд. Осваиваю главу 12.6 Статические члены класса. В...


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

Или воспользуйтесь поиском по форуму:
11
Ответ Создать тему
Новые блоги и статьи
Философия технологии
iceja 01.02.2026
На мой взгляд у человека в технических проектах остается роль генерального директора. Все остальное нейронки делают уже лучше человека. Они не могут нести предпринимательские риски, не могут. . .
SDL3 для Web (WebAssembly): Вывод текста со шрифтом TTF с помощью SDL3_ttf
8Observer8 01.02.2026
Содержание блога В этой пошаговой инструкции создадим с нуля веб-приложение, которое выводит текст в окне браузера. Запустим на Android на локальном сервере. Загрузим Release на бесплатный. . .
SDL3 для Web (WebAssembly): Сборка C/C++ проекта из консоли
8Observer8 30.01.2026
Содержание блога Если вы откроете примеры для начинающих на официальном репозитории SDL3 в папке: examples, то вы увидите, что все примеры используют следующие четыре обязательные функции, а. . .
SDL3 для Web (WebAssembly): Установка Emscripten SDK (emsdk) и CMake для сборки C и C++ приложений в Wasm
8Observer8 30.01.2026
Содержание блога Для того чтобы скачать Emscripten SDK (emsdk) необходимо сначало скачать и уставить Git: Install for Windows. Следуйте стандартной процедуре установки Git через установщик. . . .
SDL3 для Android: Подключение Box2D v3, физика и отрисовка коллайдеров
8Observer8 29.01.2026
Содержание блога Box2D - это библиотека для 2D физики для анимаций и игр. С её помощью можно определять были ли коллизии между конкретными объектами. Версия v3 была полностью переписана на Си, в. . .
Инструменты COM: Сохранение данный из VARIANT в файл и загрузка из файла в VARIANT
bedvit 28.01.2026
Сохранение базовых типов COM и массивов (одномерных или двухмерных) любой вложенности (деревья) в файл, с возможностью выбора алгоритмов сжатия и шифрования. Часть библиотеки BedvitCOM Использованы. . .
SDL3 для Android: Загрузка PNG с альфа-каналом с помощью SDL_LoadPNG (без SDL3_image)
8Observer8 28.01.2026
Содержание блога SDL3 имеет собственные средства для загрузки и отображения PNG-файлов с альфа-каналом и базовой работы с ними. В этой инструкции используется функция SDL_LoadPNG(), которая. . .
SDL3 для Android: Загрузка PNG с альфа-каналом с помощью SDL3_image
8Observer8 27.01.2026
Содержание блога SDL3_image - это библиотека для загрузки и работы с изображениями. Эта пошаговая инструкция покажет, как загрузить и вывести на экран смартфона картинку с альфа-каналом, то есть с. . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2026, CyberForum.ru