Форум программистов, компьютерный форум, киберфорум
С++ для начинающих
Войти
Регистрация
Восстановить пароль
Блоги Сообщество Поиск Заказать работу  
 
 
Рейтинг 4.93/103: Рейтинг темы: голосов - 103, средняя оценка - 4.93
30 / 47 / 19
Регистрация: 23.10.2014
Сообщений: 1,001

Количество объектов класса

31.01.2015, 15:47. Показов 22674. Ответов 21
Метки нет (Все метки)

Студворк — интернет-сервис помощи студентам
недавно подцепил тут где то этот вопрос и меня что называется зацепило... думал думал так и не смог придумать как сделать счетчик созданных объектов класса? знаю статичная переменная бла бла бла... но не так то просто...
C++
1
2
3
4
5
6
7
8
class A
{
    static size_t m_count = 0;
public:
    A() { m_count++; }
    ~A() { m_count--; }
    const size_t& count = m_count;
};
казалось бы все правильно, но ! "error C2864: "A::m_count": статический элемент данных с инициализатором внутри класса должен иметь неизменяемый целочисленный тип const", а ведь инициализировать нулем ее так или иначе надо, чтобы было откуда инкрементировать... вот и задачка на засыпку
0
Лучшие ответы (1)
cpp_developer
Эксперт
20123 / 5690 / 1417
Регистрация: 09.04.2010
Сообщений: 22,546
Блог
31.01.2015, 15:47
Ответы с готовыми решениями:

Узнать размер (количество) массива объектов класса
Допустим, у меня есть такой массив объектов: TGameEnemy enemies = { TGameEnemy(), TGameEnemy(), TGameEnemy() }; Мне необходимо...

Массив объектов одного класса как поле другого класса
Доброе время суток. Мне тут в универе задали лабу, нужно создать класс полем которого будет массив объектов класса из предыдущей лабы и в...

Построение описания класса, создание и уничтожение объектов этого класса
Построить описание класса, содержащего информацию о почтовом адресе организации. Предусмотреть возможность раздельного изменения...

21
Рожденная для битвы
 Аватар для marina2
294 / 72 / 15
Регистрация: 08.11.2009
Сообщений: 1,272
31.01.2015, 15:54
Цитата Сообщение от Dark Byte Посмотреть сообщение
const size_t& count = m_count;
Зачем это?
0
Эксперт С++
 Аватар для hoggy
8973 / 4319 / 960
Регистрация: 15.11.2014
Сообщений: 9,760
31.01.2015, 15:55
Лучший ответ Сообщение было отмечено Dark Byte как решение

Решение

Есть два пути.

Плохой:

C++
1
2
3
4
5
6
7
8
9
class A
{
    static size_t sCount;
public:
    A()   { ++sCount; } //<--- для нормального счетчика экземпляра
    ~A() { --sCount;  }//<--- необходимо педалить эту ботву во всех конструкторах
            //включая конструкторы копий, и перемещения.
};
 size_t A::sCount= 0;  //<--- зависимость от порядка инициализаций ед. трансляций
И хороший:
C++
1
2
3
4
5
6
7
8
9
10
11
12
class A
{
public:
    A()   { ++Count(); } //<--- для нормального счетчика экземпляра
    ~A() { --Count();  }//<--- необходимо педалить эту ботву во всех конструкторах
            //включая конструкторы копий, и перемещения.
 
private:
 
    // не зависит от порядка инициализаций ед. трансляций
    size_t& Count() { static size_t c=0; return c; }
};
Добавлено через 24 секунды
Цитата Сообщение от marina2 Посмотреть сообщение
Зачем это?
Это такая киллер-фича: "недо-проперти местного умельца"
3
30 / 47 / 19
Регистрация: 23.10.2014
Сообщений: 1,001
31.01.2015, 15:55  [ТС]
Цитата Сообщение от marina2 Посмотреть сообщение
Зачем это?
это моя альтернатива отсутствующим в плюсах property, работает правда только как геттер, если вам так будет привычнее можете сделать аналогичную функцию возвращающую count, смысл тот же...
0
30 / 47 / 19
Регистрация: 23.10.2014
Сообщений: 1,001
31.01.2015, 16:03  [ТС]
и маленькое добавление от изобретателя супер фичи !
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
class A
{
private:
    size_t& m_count()
    {
        static size_t c(0);
        return c;
    }
 
public:
    A() { m_count()++; }
 
    ~A() { m_count()--; }
 
    const size_t& count = m_count();
};
0
:)
Эксперт С++
4773 / 3267 / 497
Регистрация: 19.02.2013
Сообщений: 9,046
31.01.2015, 16:30
Цитата Сообщение от Dark Byte Посмотреть сообщение
и маленькое добавление от изобретателя супер фичи !
Интересно послушать обоснование необходимости этого добавления.
0
30 / 47 / 19
Регистрация: 23.10.2014
Сообщений: 1,001
31.01.2015, 16:44  [ТС]
Цитата Сообщение от Tulosba Посмотреть сообщение
Интересно послушать обоснование необходимости этого добавления.
удобство использования не надо писать скобочки
0
Эксперт С++
 Аватар для hoggy
8973 / 4319 / 960
Регистрация: 15.11.2014
Сообщений: 9,760
31.01.2015, 16:53
Цитата Сообщение от Dark Byte Посмотреть сообщение
и маленькое добавление от изобретателя супер фичи
Такие вещи, как "счетчик экземпляров" выносят в отдельные "утилитарные классы".
Что бы их функционал легко можно было подключать к любому заинтересованному классу:

http://rextester.com/EJQH24580


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
58
59
//делается простенький шаблончик
 
#include <cstddef>
 
template<class T> struct numcopies
{
    static size_t copies() { return counter(); }
protected:
   ~numcopies()                  { --counter(); }    
    numcopies()                  { ++counter(); }    
    numcopies(const numcopies&)  { ++counter(); }    
private:
    static size_t& counter() { static size_t c=0; return c; }
};
 
 
// далее от него наследуется любой класс, 
// который хочет заполучить функционал "счетчик экземпляров"
struct sample: numcopies<sample>
{
    typedef numcopies<sample>
        parent;
    
    sample(){}
    
    sample(const sample& s)
        :parent(s)
    {}
    sample(const sample&& s)
        :parent(s)
    {}
    
};
 
// ну а дальше уже можно использовать:
 
#include <iostream>
 
sample foo() { return sample(); }
 
int main()
{
    std::cout << "Hello, world!\n";
    
    {
        sample s;
        {
            sample s1;
            auto s2 = s1;
            {
                sample ss( foo() );
            }
        }
        
    }
    
    std::cout<<"number of samples: "<< sample::copies()<<" (must be 0)\n";
        
}
2
:)
Эксперт С++
4773 / 3267 / 497
Регистрация: 19.02.2013
Сообщений: 9,046
31.01.2015, 17:19
Цитата Сообщение от Dark Byte Посмотреть сообщение
не надо писать скобочки
Скобочки уходят, зато увеличивается размер объекта класса. А это более неприятный момент, чем лишние скобочки.
0
30 / 47 / 19
Регистрация: 23.10.2014
Сообщений: 1,001
31.01.2015, 18:44  [ТС]
hoggy, хорошая идея кстати только я не понял зачем вы туда шаблоны прикрутили и тайпдеф? просто пронаследовали и все !
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
class numcopies
{
private:
    static size_t& m_count()
    {
        static size_t c(0);
        return c;
    }
public:
    numcopies() { m_count()++; }
    ~numcopies() { m_count()--; }
    const size_t& count = m_count();
};
 
class A : public numcopies
{
};
з.ы. кстати вы забыли наследовать публично !
0
Эксперт С++
 Аватар для hoggy
8973 / 4319 / 960
Регистрация: 15.11.2014
Сообщений: 9,760
31.01.2015, 19:09
#9 корявое.

В нем допущена избыточность.

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
//делается простенький шаблончик
 
#include <cstddef>
 
template<class T> struct numcopies
{
    static size_t copies() { return counter(); }
protected:
   ~numcopies()    { --counter(); }    // <--- достаточно только 1 конструктор
    numcopies()     { ++counter(); }  //  и диструктор
private:
    static size_t& counter() { static size_t c=0; return c; }
};
 
 
// далее от него наследуется любой класс, 
// который хочет заполучить функционал "счетчик экземпляров"
struct sample: numcopies<sample>
{
    
    sample(){}
    
    sample(const sample& s)  {}    //<--- наследник может определять любые свои конструкторы
    sample(const sample&& s) {}  // при этом не нужно указывать 
                        //запуски конструкторов базового класса
    
};
 
// ну а дальше уже можно использовать:
 
#include <iostream>
 
sample foo() { return sample(); }
 
int main()
{
    std::cout << "Hello, world!\n";
    
    {
        sample s;
        {
            sample s1;
            auto s2 = s1;
            {
                sample ss( foo() );
            }
        }
        
    }
    
    std::cout<<"number of samples: "<< sample::copies()<<" (must be 0)\n";
        
}
----------------------------------------------------------------------

Это довольно таки любопытный момент, о котором иногда забывают:
(например, я только что протупил)

По умолчанию компилятор запускает только "конструкторы по умолчанию".

Поэтому при создании наследника любым конструктором, для базового класса-счетчика всегда запустится конструктор с инкрементом счетчика

Добавлено через 27 секунд
Цитата Сообщение от Dark Byte Посмотреть сообщение
з.ы. кстати вы забыли наследовать публично !
Нет. Не забыл.

Добавлено через 2 минуты
Цитата Сообщение от Dark Byte Посмотреть сообщение
только я не понял зачем вы туда шаблоны прикрутили
попробуйте без шаблона создать два класса.

Один назовем bar
А другой baz.

Создайте 3 экземпляра класса bar
И 2 экземпляра класса baz.

Выведете на экран отдельно количество экземпляров bar. И отдельно количество экземпляров baz
0
30 / 47 / 19
Регистрация: 23.10.2014
Сообщений: 1,001
31.01.2015, 19:22  [ТС]
Цитата Сообщение от hoggy Посмотреть сообщение
~numcopies() * *{ --counter(); } * *// <--- достаточно только 1 конструктор
это деструктор
Цитата Сообщение от hoggy Посмотреть сообщение
numcopies() * * { ++counter(); } *// *и диструктор
это конструктор и деструктор пишется через Е
Цитата Сообщение от hoggy Посмотреть сообщение
попробуйте без шаблона создать два класса.
Один назовем bar
А другой baz.
Создайте 3 экземпляра класса bar
И 2 экземпляра класса baz.
оба наследуются от numcopies? сделал, copies == 5

Добавлено через 1 минуту
Цитата Сообщение от Dark Byte Посмотреть сообщение
copies == 5
аа вот че... ну да с шаблонами норм прокатывает
0
Эксперт С++
 Аватар для hoggy
8973 / 4319 / 960
Регистрация: 15.11.2014
Сообщений: 9,760
31.01.2015, 19:24
Цитата Сообщение от Dark Byte Посмотреть сообщение
оба наследуются от numcopies? сделал, copies == 5
у вас получилось 5 штук баров и 5 штук базов?

Добавлено через 1 минуту
Цитата Сообщение от Dark Byte Посмотреть сообщение
аа вот че... ну да с шаблонами норм прокатывает
надеюсь я ответил на ваш вопрос.
0
30 / 47 / 19
Регистрация: 23.10.2014
Сообщений: 1,001
31.01.2015, 19:29  [ТС]
Цитата Сообщение от hoggy Посмотреть сообщение
надеюсь я ответил на ваш вопрос.
еще не совсем, а если пронаследовать от numcopies класс и от этого класса пронаследовать другой класс?
C++
1
2
class A : public numcopies<A> {};
class B : public A {}
так вот в данном случае numcopies будет опять таки не правильно работать... как сделать для B отдельно?
0
Эксперт С++
 Аватар для hoggy
8973 / 4319 / 960
Регистрация: 15.11.2014
Сообщений: 9,760
31.01.2015, 19:31
Цитата Сообщение от Dark Byte Посмотреть сообщение
так вот в данном случае numcopies будет опять таки не правильно работать... как сделать для B отдельно?
C++
1
2
3
4
5
6
class A : public numcopies<A> {};
 
class B 
    : numcopies<B>
    , public A 
{}
1
30 / 47 / 19
Регистрация: 23.10.2014
Сообщений: 1,001
31.01.2015, 19:34  [ТС]
hoggy, error C2247: нет доступа к "numcopies<B>::copies", поскольку "B" использует "private" для наследования из "numcopies<B>"
0
19500 / 10105 / 2461
Регистрация: 30.01.2014
Сообщений: 17,816
31.01.2015, 19:36
Цитата Сообщение от Dark Byte Посмотреть сообщение
з.ы. кстати вы забыли наследовать публично !
Для структур наследование по-умолчанию публично.
Для классов - по-умолчанию приватно.
У него в примере были везде структуры, значит указание наследования без типа будет означать публичное. С классом - наоборот, приватное.
0
Эксперт С++
 Аватар для hoggy
8973 / 4319 / 960
Регистрация: 15.11.2014
Сообщений: 9,760
31.01.2015, 19:39
Цитата Сообщение от Dark Byte Посмотреть сообщение
hoggy, error C2247: нет доступа к "Origin::numcopies<B>::copies", поскольку "B" использует "private" для наследования из "Origin::numcopies<B>"
Ну и что?

Когда вы меняли struct numcopies, на class numcopies, вы осознавали последствия?
Если нет - вертите как было.

Если да - сами исправляйте все ошибки. Чего вы мне то их показываете?
0
30 / 47 / 19
Регистрация: 23.10.2014
Сообщений: 1,001
31.01.2015, 19:48  [ТС]
хорошо хорошо, я не заметил просто что у вас была структура, но все равно ошибок только прибавилось
error C2385: неоднозначный уровень доступа "copies"
1> может быть "copies" в базе "numcopies<B>"
1> или может быть "copies" в базе "numcopies<A>"
error C2247: нет доступа к "numcopies<B>::copies", поскольку "B" использует "private" для наследования из "numcopies<B>"
0
Эксперт С++
 Аватар для hoggy
8973 / 4319 / 960
Регистрация: 15.11.2014
Сообщений: 9,760
31.01.2015, 19:57
http://rextester.com/ZHSQZ73353

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
#include <cstddef>
 
template<class T> struct numcopies
{
    static size_t copies() { return counter(); }
protected:
   ~numcopies() { --counter(); } 
    numcopies() { ++counter(); } 
private:
    static size_t& counter() { static size_t c=0; return c; }
};
//----------------------------------------------------------------
 
 
class A : public numcopies<A> {};
 
class B 
    : numcopies<B>
    , public A 
{
public:
        using numcopies<B>::copies;
};
 
 
#include <iostream>
 
 
int main()
{
    std::cout << "Hello, world!\n";
    B b;
    
    std::cout<<"number of samples: "<< B::copies()<<" (must be 1)\n";
}
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
raxper
Эксперт
30234 / 6612 / 1498
Регистрация: 28.12.2010
Сообщений: 21,154
Блог
31.01.2015, 19:57
Помогаю со студенческими работами здесь

Реализовать подсчет количества объектов класса, используя статическую переменную-член класса
как реализовать подсчет количества объектов класса (используя статическую переменную-член класса), а также статическую функцию, которая...

Массив объектов класса. Печать строк-членов класса.
подскажите, как распечатать строки? #include &quot;myString.h&quot; #include &lt;iostream&gt; #define stop __asm nop void main() { ...

Массив объектов класса как член другого класса
Здравствуйте. У меня тут возникла проблемка #include &quot;main.h&quot; class player { public: player(); player(char*); ...

Инициализация объектов класса в конструкторе другого класса
У меня есть класс Subscriber,в котором есть несколько объектов другого класса Date,мне нужно,чтобы при создании Subscriber объекты класса...

Массив объектов класса
Добрый день. При попытки создать массив объектов класса ошибка. Как в дальнейшем динамически изменять размер массива (добавлять-удалять...


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

Или воспользуйтесь поиском по форуму:
20
Ответ Создать тему
Новые блоги и статьи
SDL3 для Web (WebAssembly): Реализация движения на Box2D v3 - трение и коллизии с повёрнутыми стенами
8Observer8 20.02.2026
Содержание блога Box2D позволяет легко создать главного героя, который не проходит сквозь стены и перемещается с заданным трением о препятствия, которые можно располагать под углом, как верхнее. . .
Конвертировать закладки radiotray-ng в m3u-плейлист
damix 19.02.2026
Это можно сделать скриптом для PowerShell. Использование . \СonvertRadiotrayToM3U. ps1 <path_to_bookmarks. json> Рядом с файлом bookmarks. json появится файл bookmarks. m3u с результатом. # Check if. . .
Семь CDC на одном интерфейсе: 5 U[S]ARTов, 1 CAN и 1 SSI
Eddy_Em 18.02.2026
Постепенно допиливаю свою "многоинтерфейсную плату". Выглядит вот так: https:/ / www. cyberforum. ru/ blog_attachment. php?attachmentid=11617&stc=1&d=1771445347 Основана на STM32F303RBT6. На борту пять. . .
Камера Toupcam IUA500KMA
Eddy_Em 12.02.2026
Т. к. у всяких "хикроботов" слишком уж мелкий пиксель, для подсмотра в ESPriF они вообще плохо годятся: уже 14 величину можно рассмотреть еле-еле лишь на экспозициях под 3 секунды (а то и больше),. . .
И ясному Солнцу
zbw 12.02.2026
И ясному Солнцу, и светлой Луне. В мире покоя нет и люди не могут жить в тишине. А жить им немного лет.
«Знание-Сила»
zbw 12.02.2026
«Знание-Сила» «Время-Деньги» «Деньги -Пуля»
SDL3 для Web (WebAssembly): Подключение Box2D v3, физика и отрисовка коллайдеров
8Observer8 12.02.2026
Содержание блога Box2D - это библиотека для 2D физики для анимаций и игр. С её помощью можно определять были ли коллизии между конкретными объектами и вызывать обработчики событий столкновения. . . .
SDL3 для Web (WebAssembly): Загрузка PNG с прозрачным фоном с помощью SDL_LoadPNG (без SDL3_image)
8Observer8 11.02.2026
Содержание блога Библиотека SDL3 содержит встроенные инструменты для базовой работы с изображениями - без использования библиотеки SDL3_image. Пошагово создадим проект для загрузки изображения. . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2026, CyberForum.ru