Форум программистов, компьютерный форум, киберфорум
С++ для начинающих
Войти
Регистрация
Восстановить пароль
Блоги Сообщество Поиск  
 
 
Рейтинг 4.60/42: Рейтинг темы: голосов - 42, средняя оценка - 4.60
16 / 18 / 2
Регистрация: 02.03.2024
Сообщений: 510

Статический класс

25.04.2024, 04:02. Показов 10744. Ответов 165
Метки нет (Все метки)

Студворк — интернет-сервис помощи студентам
Всем привет
хочу создать полностью статический класс и создаю
но возникают ошибки неопределенные reference и пр.

хотелось бы сделать так
C#
1
2
3
4
5
6
7
static class SomeClass{
 
 
public int var1{}, var2{}, var3{};
......
 
}
но в с++ ругается на static перед словом класс
пишу в итоге так
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
class SomeClass{
 
SomeClass(){};
public:
 
static float var1{}, var2{}, varN{}; 
static float somethingMethod(){
//тут использую переменные var1, var2....
};
 
//static float var1{}, var2{}, varN{}; // без разницы   где объявляю переменные выше или ниже метода,  ругается не необъявленные переменные
 
 
 
}
 
 
//
 
вызываю так 
SomeClass::somethingMethod();

при компиляции получаю ошибки
необъявленные ссылки на var1, var2 ....

undefined reference to `SomeClass::var1


вопрос
как объявить статический метод класса, а в идеале и вообще весь класс, чтобы не создавать в коде его экземпляр?

Добавлено через 4 минуты
основная задача вынести этот статический класс в один файл то бишь в модуль не хедер + cpp а сразу все
в одном как в шарпах - очень удобно это они придумали в шарпах
0
cpp_developer
Эксперт
20123 / 5690 / 1417
Регистрация: 09.04.2010
Сообщений: 22,546
Блог
25.04.2024, 04:02
Ответы с готовыми решениями:

Дан класс, преобразуйте его в статический класс со статическими методами и продемонстрируйте работу с ним
Дан класс, преобразуйте его в статический класс со статическими методами и продемонстрируйте работу с ним.

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

Статический член указатель на класс
Доброго времени суток. Что требовалось: создать статический указатель на класс CPerson, чтобы сохранить в него нужный объект. Как пытался...

165
19501 / 10106 / 2461
Регистрация: 30.01.2014
Сообщений: 17,825
25.04.2024, 19:43
Студворк — интернет-сервис помощи студентам
Цитата Сообщение от pup_kin Посмотреть сообщение
получается рабочий только вариант с namespace,
а внутрь него положить статику и класс.
Других вариантов нет?
Я ж, блин, сразу вам написал
Цитата Сообщение от DrOffset Посмотреть сообщение
pup_kin, static inline для var1, var2.
Добавлено через 20 секунд
Цитата Сообщение от pup_kin Посмотреть сообщение
проверял - без разницы
Плохо проверяли.

Добавлено через 2 минуты
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
#include <memory>
#include <cstdlib>
#include <iostream>
 
class A {
public:
    static inline int var1, var2, varN;
 
    static void Method() {
        var1++;
        std::cout << var1 << '\n';
    };
};
 
int main()
{
    A::Method(); // ничего не ругается
}
0
16 / 18 / 2
Регистрация: 02.03.2024
Сообщений: 510
25.04.2024, 19:43  [ТС]
Цитата Сообщение от DrOffset Посмотреть сообщение
static inline для var1, var2.
это для какого варианта?

а какой смысл tatic inline
если это вариант не тот, и если оно и без inline работает.
я вот вообще не понял причем здесь inline.


вопрос простой -
можно ли без нейм спейс реализовать ?
если можно - буду тестировать inline
если нет - то какой смысл писать inline -если все равно не то.
0
19501 / 10106 / 2461
Регистрация: 30.01.2014
Сообщений: 17,825
25.04.2024, 19:54
Цитата Сообщение от pup_kin Посмотреть сообщение
это для какого варианта?
Для варианта из шапки темы.

Цитата Сообщение от pup_kin Посмотреть сообщение
если это вариант не тот, и если оно и без inline работает.
Тот.
Без inline у вас "undefined reference to `SomeClass::var1"

Цитата Сообщение от pup_kin Посмотреть сообщение
я вот вообще не понял причем здесь inline.
Объяснили же в теме выше зачем он.

Добавлено через 1 минуту
Цитата Сообщение от pup_kin Посмотреть сообщение
вопрос простой -
можно ли без нейм спейс реализовать ?
Можно. Пробуйте лучше, без суеты и поспешных выводов.

Добавлено через 7 минут
pup_kin, https://wandbox.org/permlink/FRTcumqTXRHBT1ZD
C inline все работает.
Кликните здесь для просмотра всего текста
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
#include <memory>
#include <cstdlib>
#include <iostream>
 
struct  A {
public:
    static inline int var1, var2, varN;
 
    static void Method() {
        var1++;
        std::cout << var1 << '\n';
    };
};
 
int main()
{
    A::Method();
}

Убираю inline
Кликните здесь для просмотра всего текста
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
#include <memory>
#include <cstdlib>
#include <iostream>
 
struct  A {
public:
    static int var1, var2, varN;
 
    static void Method() {
        var1++;
        std::cout << var1 << '\n';
    };
};
 
int main()
{
    A::Method();
}

Получаем ошибки линковки: https://wandbox.org/permlink/xVziDy2x03yfk7Li

Нагляднее некуда. Пробуйте.
1
фрилансер
 Аватар для Алексей1153
6495 / 5724 / 1133
Регистрация: 11.10.2019
Сообщений: 15,286
25.04.2024, 20:08
Цитата Сообщение от sdf45 Посмотреть сообщение
тогда можно будет обьект класса создать вроде
можно, на здоровье )
0
Покинул чат.
1133 / 728 / 195
Регистрация: 30.03.2021
Сообщений: 2,379
25.04.2024, 20:13
Алексей1153, там просто у ТС хотелка такая, что бы обьект нельзя было создать (во вс. случае, я понял так)
Вообще наверное, стоило бы ему упомянуть про синглтон, но походу рановато еще...
0
 Аватар для SmallEvil
4086 / 2975 / 813
Регистрация: 29.06.2020
Сообщений: 11,000
25.04.2024, 20:16
Цитата Сообщение от sdf45 Посмотреть сообщение
там просто у ТС
золиварщик
0
фрилансер
 Аватар для Алексей1153
6495 / 5724 / 1133
Регистрация: 11.10.2019
Сообщений: 15,286
25.04.2024, 20:17
sdf45, если он и создаст объект, от этого ничего не произойдёт, ведь все элементы статические
0
Покинул чат.
1133 / 728 / 195
Регистрация: 30.03.2021
Сообщений: 2,379
25.04.2024, 20:21
Цитата Сообщение от SmallEvil Посмотреть сообщение
золиварщик
SmallEvil, что значит это слово? холиварщик? почему?
Вот почему я так предположил:
Цитата Сообщение от pup_kin Посмотреть сообщение
как объявить статический метод класса, а в идеале и вообще весь класс, чтобы не создавать в коде его экземпляр?


Цитата Сообщение от Алексей1153 Посмотреть сообщение
если он и создаст объект, от этого ничего не произойдёт, ведь все элементы статические
Хотя мне как-то совсем пофиг, пусть создает.
0
16 / 18 / 2
Регистрация: 02.03.2024
Сообщений: 510
25.04.2024, 20:22  [ТС]
C++
1
2
3
4
5
6
7
8
9
class A {
public:
    static inline int var1, var2, varN;
 
    static void Method() {
        var1++;
        std::cout << var1 << '\n';
    };
};

я то проверял на 14 стандарте
на 17 м все работает
спасибо

удивительно и в ардуине оно работает.
всем спасибо

но если в ардуине inline убрать
то оно ругается не так как в визуал студио
и вообще ошибку не понять занятно. ругается на SD card ^)
0
16 / 18 / 2
Регистрация: 02.03.2024
Сообщений: 510
26.04.2024, 02:47  [ТС]
почитал так
осмыслил
и возникает вопрос
почему для полей нужен inline для того чтобы объявить их статическими,
а для метода не нужен.
ведь и метод и поле имеют адрес и тип возвращаемого значения.


поигрался
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
class A {
public:
    static inline int var1=1, var2=2, varN =3;
 
    static inline void Method() {
        var1++;
        std::cout << var1 << '\n';
    };
 
    static void Method2() {
        var1++;
        std::cout << var1 << '\n';
    };
 
    static void Method3() {
        var1++;
        std::cout << var1 << '\n';
    };
};
оказалось - наличие inline у метода не приводит к каким либо плачевным последствиям.

Вопрос "inline" который у метода - это будет тот же самый inline который у поля, или здесь будет подстановка кода в вызываемое место?

как вообще inline стало влиять на one definition rule?
что происходит если просто пишу static - каким образом не происходит определение полей, ведь они же заданы но при этом ругается на undefined reference


какой смысл имеет определение
static int var5;// например?

обратиться к var5 как к статическому полю я не могу,
обратиться из экземпляра класса - тоже не могу.
А какой тогда его смысл без inline?

или это все заиграет когда будет хедер+ cpp и/или внешние определения?
0
19501 / 10106 / 2461
Регистрация: 30.01.2014
Сообщений: 17,825
26.04.2024, 08:39
Цитата Сообщение от pup_kin Посмотреть сообщение
Вопрос "inline" который у метода - это будет тот же самый inline который у поля, или здесь будет подстановка кода в вызываемое место?
Тот же самый. Будет подстановка или не будет - решает компилятор, inline на это никак не влияет.

Цитата Сообщение от pup_kin Посмотреть сообщение
как вообще inline стало влиять на one definition rule?
Это техническая необходимость. Если у вас в разных единицах трансляции появляется одинаковые определения, то с этим надо что-то делать. Если вы помещаете определение в заголовочный файл, а потом подключаете его в нескольких cpp - у вас появляется несколько определений в программе, что недопустимо. Чтобы избежать этого, линкер научили выбрасывать одинаковые определения, помеченные определенным образом (в данном случае Inline как раз и добавляет эту пометку), т.е. оставлять в итоговом коде только одно. Потребность делать это возникла для всех сущностей, которые могут быть определены в заголовочном файле: inline-функции, шаблоны, а теперь и переменные.

Цитата Сообщение от pup_kin Посмотреть сообщение
оказалось - наличие inline у метода не приводит к каким либо плачевным последствиям.
"Метод", определенный прямо в теле класса и так неявно inline. Это правило языка.

Цитата Сообщение от pup_kin Посмотреть сообщение
какой смысл имеет определение
static int var5;// например?
Это не определение, а объявление.
Определение для такого объявления должно быть вне класса, по тому же принципу, что и аналогичный код для функции.
C++
1
2
3
4
5
6
7
8
9
10
11
12
class A {
public:
    static int var5; // объявление
 
    static void foo(); // объявление
};
 
int A::var5; // определение
 
void A::foo()  // определение
{
}
Но размещать определение в таком виде в заголовочном файле не получится, из-за ODR и принципа раздельной компиляции. Чтобы преодолеть это, определение можно пометить inline, тогда линковщик сможет понять, что это не разные определения, а одно и то же и выбросить дубликаты.
C++
1
2
3
4
5
6
7
8
9
10
11
12
class A {
public:
    static int var5; // объявление
 
    static void foo(); // объявление
};
 
inline int A::var5; // определение (inline)
 
inline void A::foo()  // определение (inline)
{
}
ну и в C++ можно совместить, объявление и определение, оставив его в теле класса. Для переменных такое возможно только с использованием явного inline, а функции приобретают свойство inline в этом случае неявно.

Цитата Сообщение от pup_kin Посмотреть сообщение
или это все заиграет когда будет хедер+ cpp ?
Да.

Добавлено через 6 минут
Цитата Сообщение от pup_kin Посмотреть сообщение
почему для полей нужен inline для того чтобы объявить их статическими,
а для метода не нужен.
Тут все перепутано у вас.
Статическое поле обязано иметь определение. Функции могут иметь его по месту, прямо в теле класса и тогда это определение будет считаться inline. Переменные в прежних версиях языка могли быть определены только вне класса (как я показывал выше). Относительно недавно добавили возможность определить переменную прямо в теле класса с ключевым словом inline.
Таким образом статическим переменным и функциям не обязательно быть inline. Им всего лишь нужно определение. А вот каким образом вы это определение предоставите, уже зависит от использование или неиспользования inline. Если нужно его (определение) предоставить в теле класса, или просто сделать доступным в заголовочном файле, то inline нужно будет использовать обязательно.
1
 Аватар для SmallEvil
4086 / 2975 / 813
Регистрация: 29.06.2020
Сообщений: 11,000
26.04.2024, 15:36
Цитата Сообщение от sdf45 Посмотреть сообщение
что значит это слово?
Моя не понима, как можно быть взрослым и не понимать азы!
Цитата Сообщение от sdf45 Посмотреть сообщение
почему?
Цитата Сообщение от pup_kin Посмотреть сообщение
Статический класс в С++
Такого понятия даже в С# не существует!
0
16 / 18 / 2
Регистрация: 02.03.2024
Сообщений: 510
26.04.2024, 17:43  [ТС]
Цитата Сообщение от SmallEvil Посмотреть сообщение
Такого понятия даже в С# не существует!
это да, потому что он лишен смысла
полностью и ТОЛЬКО статический класс - лишен смысла, он превращается в недо namespace.

это я неверно выразился - потому что стояла задача именно в необходимости статичных методов - потом это конечно вынесется в отдельный файл, и чтобы все было в одном файле и в одном классе - как в модуле, модули в 1С есть про модули с++ не знал.

DrOffset ну конечно я имею ввиду объявление , когда речь идет про поля.
но изначально когда писал, а потом стер "= занчениеПрисваивания",

сейчас работает в том числе и константными полями
C++
1
2
3
4
5
6
class A {
public:
    int var5 = 5;
    const int var9 = 9;
    static inline int var1=1, var2=2, varN =3;
    static const inline int var7=7;
т.е. понятно, что когда есть хедер и в хедере есть реализация, то получится множественное добавление.

а вот вопрос
директивы
C++
1
pragma once
или

C++
1
2
if not def ИМЯ_ХЕДЕРА 
....
они разве не избавляют от проблем с множественными определениями и даже объявлениями?

для чего потребовалось использовать также и inline.
хронология возникновения и в целом проблемы решаемые не ясны.
0
19501 / 10106 / 2461
Регистрация: 30.01.2014
Сообщений: 17,825
26.04.2024, 18:13
Цитата Сообщение от pup_kin Посмотреть сообщение
они разве не избавляют от проблем с множественными определениями и даже объявлениями?
Они избавляют только от повторного включение в одну и ту же единицу трансляции.
Если единицы трансляции разные, то они не помогут ничем. Помните про принцип раздельной компиляции.

Добавлено через 35 секунд
Цитата Сообщение от pup_kin Посмотреть сообщение
хронология возникновения и в целом проблемы решаемые не ясны.
Будут ясны, если понять что такое раздельная компиляция.

Добавлено через 3 минуты
pup_kin, https://youtu.be/G_jcBrrYPAs?t=89
1
 Аватар для eva2326
1685 / 513 / 107
Регистрация: 17.05.2015
Сообщений: 1,524
26.04.2024, 18:16
Цитата Сообщение от pup_kin Посмотреть сообщение
они разве не избавляют от проблем с множественными определениями и даже объявлениями?
для чего потребовалось использовать также и inline.
хронология возникновения и в целом проблемы решаемые не ясны.

Например у вас есть заголовочный файл:

C++
1
2
3
// foo.hpp
#pragma once
void foo(){}
И вы прицепляете его к двух разным ед. трансляции:

C++
1
2
3
//main.cpp
#include "foo.hpp"
int main(){}
C++
1
2
3
//bar.cpp
#include "foo.hpp"
void bar(){}
В языке с++ компиляция раздельная.
Это значит, что компилятор будет по отдельности компилировать main.cpp и bar.cpp
И когда он скомпилирует, например файл main.cpp, то он скомпилирует функцию void foo(){}
А потом он скомпилирует файл bar.cpp, и тоже скомпилирует функцию void foo(){}

Получится, что функция void foo(){} была скомпилирована дважды.
И когда потом линкер будет собирать все объектные файлы воедино, он выдаст ошибку о том, что функция foo имеет несколько определений.
По правилам языка такого быть не должно, поэтому линкер сгенерирует ошибку.
Однако, если вы пометите функцию как встраиваемую:

C++
1
2
3
// foo.hpp
#pragma once
inline void foo(){}
Тогда ошибок линковки уже не будет, поскольку по правилам языка с++, inline функциям разрешается иметь несколько определений, при условии, что эти определения существуют в разных ед. трансляции, и при условии, что все определения имеют одинаковую реализацию.
В этом случае линкер просто удалит лишние дубли, оставив только одну какую то версию.
2
16 / 18 / 2
Регистрация: 02.03.2024
Сообщений: 510
26.04.2024, 18:19  [ТС]
кажется понимаю.
а как это реализовано.
это компиляторы научились как-то сохранять данные куда-то в кеш при работе с несколькими единицами трансляции.

занятно , надо почитать

кстати читаю про модули с ++
https://en.cppreference.com/w/cpp/language/modules
и тут написано модули ортогональны пространствам имен
как это понять ?
ортогональный тип.
я так понимаю что в данном случае имеется ввиду сто модули с++ родственны пространствам имен.

Добавлено через 1 минуту
а если компиляция раздельная,
то как раньше существовали без inline ?
0
19501 / 10106 / 2461
Регистрация: 30.01.2014
Сообщений: 17,825
26.04.2024, 18:46
Цитата Сообщение от pup_kin Посмотреть сообщение
то как раньше существовали без inline ?
Так inline был, его только для переменных не было.
Определение переменной размещалось в cpp и все.

Видео посмотрите.

Добавлено через 2 минуты
Цитата Сообщение от pup_kin Посмотреть сообщение
как это понять ?
ортогональный тип.
я так понимаю что в данном случае имеется ввиду сто модули с++ родственны пространствам имен.
Ортогонально - значит перпендикулярно. То есть в естественном языке это значит, что общего мало.

Добавлено через 20 минут
Цитата Сообщение от pup_kin Посмотреть сообщение
а как это реализовано.
это компиляторы научились как-то сохранять данные куда-то в кеш при работе с несколькими единицами трансляции.
Результат компиляции единицы трансляции - объектный файл. Вот там внутри него и оставлена пометка, что данное определение нужно оставить в единственном экземпляре.
На примере GCC: https://en.wikipedia.org/wiki/Weak_symbol
1
"C with Classes"
2022 / 1404 / 523
Регистрация: 16.08.2014
Сообщений: 5,885
Записей в блоге: 1
26.04.2024, 20:22
DrOffset, к стати в VS17 есть известная проблема с static inline std::map, которая неплохо мне мозг поела когда то.
0
Эксперт функциональных языков программированияЭксперт С++
 Аватар для Royal_X
6312 / 3035 / 1053
Регистрация: 01.06.2021
Сообщений: 11,526
26.04.2024, 20:34
eva2326, DrOffset, это всё хорошо. Что делает inline всем понятно.

Но почему не написать?

C++
1
2
3
//main.cpp
#include "foo.hpp"
int main(){}
C++
1
2
3
//foo.hpp
#pragma once
void foo();
C++
1
2
3
//bar.cpp
#include "foo.hpp"
void bar(){}
C++
1
2
3
//foo.cpp
#include "foo.hpp"
void foo(){}
Зачем впихивать всё в заголовок? Он же предназначен для объявлений.
0
"C with Classes"
2022 / 1404 / 523
Регистрация: 16.08.2014
Сообщений: 5,885
Записей в блоге: 1
26.04.2024, 20:44
Цитата Сообщение от Royal_X Посмотреть сообщение
Зачем впихивать всё в заголовок?
если есть много небольших функций и хочется уменьшить лишнюю писанину (объявление + определение), то можно все небольшие функции "впихнуть" заинлайнить в заголовок.
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
raxper
Эксперт
30234 / 6612 / 1498
Регистрация: 28.12.2010
Сообщений: 21,154
Блог
26.04.2024, 20:44

Не могу вызвать простой статический класс
Вот такой код получился (VS2017): #pragma once #include &lt;iostream&gt; #include &lt;string&gt; static class Func { ...

Статический полиморфизм. Базовый класс «прямоугольник»
Здравствуйте, дорогие участники форума! Помогите, пожалуйста! Необходимо реализовать статический полиморфизм. Нужно вызвать с помощью...

Нужно создать статический массив строк как статический массив указателей на строки. Условние ниже -->
Слова английского текста рассортировать по возрастанию количества заданной буквы в слове. Слова с одинаковым количеством такой буквы...

создать статический массив строк как статический массив указателей на строки, задание ниже -->
Слова английского текста, начинающиеся с гласных букв, рассортировать в алфавитном порядке по первой согласной букве слова. Остальные слова...

Объясните человеческим языком мне чайнику что такое singleton, статический класс. Зачем они нужны. Что рекомендуете прочитать мне для начала
Объясните человеческим языком мне чайнику что такое singleton, статический класс. Зачем они нужны. Что рекомендуете прочитать мне для...


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

Или воспользуйтесь поиском по форуму:
60
Ответ Создать тему
Новые блоги и статьи
GitDOS: Когда я решил скрестить MS-DOS, GitHub и Claude
MaGz GoLd 08.07.2026
Привет, Киберфорум! Хочу поделиться своим проектом, который, надеюсь, вас заинтересует. GitDOS — это веб-приложение, которое позволяет запускать DOS в браузере с тремя крутыми фичами: диски живут в. . .
Учебный мини "цифровой двойник" = (Сервер = Java + Flask_питон )+(3D = Гугловскаая 4T nvideo + google colab) +( WMS = Odoo на Docker)
anaschu 07.07.2026
Увидел в требованиях к вакансии создателя имитационных моделей связку (REst + Api + WMS + Anylogic + питон + 3D Nvideo), и решил посмотреть, что это такое. Из этого всего я работал более менее. . .
Море в объективе
kumehtar 06.07.2026
Хотел написать много проникновенных слов, но передумал. Оно само - говорит. Кто слышит тот слышит.
Doom для терминала без стрельбы и монстров. 3D Raycasting на ascii.
dcc0 05.07.2026
Попросил нейронную сеть deepai. org написать рейкастинг 3D с библиотекой ncurses для Linux. Чтобы можно было ходить на стрелочки. Чтобы стены были отрисованы символами. Справилась. Первый вариант. . .
Установка статуса документа по условию
Maks 05.07.2026
Алгоритм из решения ниже реализован на нетиповом документе "НарядПутевка" разработанного в КА2. Задача: в табличной части "Материалы" документа при записи автоматически устанавливать статус. . .
Сезонность и суточность закисления почв
anaschu 04.07.2026
200 часов это все равно моловато. Есть ситуации, но нестандартные, когда смена происходит за 5 лет. Но обычно это 50 лет и более. Наверное, закисление почвы происходит сезонно в средней. . .
В чем ценность человеческого опыта в глобальном смысле?
kumehtar 03.07.2026
Возможно, ценность человека не в том, что он однажды достигает мудрости, а в том, что он становится носителем карты пути. Он знает не только истину, но и последовательность внутренних изменений,. . .
интеграция AnyLogic с самописным REST API и переход на Odoo
anaschu 03.07.2026
Успешная интеграция AnyLogic с самописным REST API и переход на промышленную Odoo WMS Сегодня проделал огромный путь от простой симуляции физических процессов до построения полноценной. . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2026, CyberForum.ru