Нужны ли глобальные переменные?

 
0
 
C++
ava
hoz | 28.08.2014, 00:52
 Есть у меня структура. Она используется практически во всех моих классах. Возник вопрос. Если оно так, то проще создать объект прямо в файле где описание данной структуры и дальше данный инклюдник с структурой и созданным объектом включить во все файлы, где описываются классы, верно?
А там уже обращаться так:

имя структуры.имя члена-элемента( метода )

Или всё-таки создавать объект глобальным плохая идея?
Просто если уж придерживаться идеологии С++. То это инкапсуляция. А в моём раскладе получается, что я  создал глобальный объект на структуру. Но по скольку структура используется везде, то другого варианта я не нашёл.
Вопрос возник по случаю, когда я читал этот пост http://forum.vingrad.ru/topic-320428.html#, где borisbn дал понять, что глобальные переменные использовать не рекомендует. Почему я не понял, но.. тем не менее.
Ответы (17)
ava
Guinness | 28.08.2014, 09:51 #
Цитата (hoz @  28.8.2014,  00:52 findReferencedText)
 Есть у меня структура. Она используется практически во всех моих классах. 

Цитата (hoz @  28.8.2014,  00:52 findReferencedText)
Если оно так, то проще создать объект прямо в файле где описание данной структуры и дальше данный инклюдник с структурой и созданным объектом включить во все файлы, где описываются классы, верно?

Так используется структура или один и тот же объект?
Цитата (hoz @  28.8.2014,  00:52 findReferencedText)
Или всё-таки создавать объект глобальным плохая идея?

Не самая здравая, особенно, если приложение достаточно большое, и в нём присутствует многопоточность. Хотя бывают случаи, когда это необходимо. Тогда в C++ используют паттерн Singleton. В C++11 он пишется несколько проще, чем в предыдущем стандарте. Однако, в любом случае геморрой с доступом к данным данной структуры Вам обеспечен.
А вообще сложно сказать, стоит ли делать глобальную переменную, ибо неизвестна архитектура приложения. В любом случае, лучше попытаться избегать глобальных переменных.
ava
hoz | 28.08.2014, 13:47 #
Цитата (Guinness @  28.8.2014,  09:51 findReferencedText)
Так используется структура или один и тот же объект?

Члены-элементы данной структуры. Бывает, что нужны члены-методы структуры или класса. Но члены являются общими для перечня других классов. Значит объект должен быть тот же, верно?
Ведь, если объект будет другой, то значение члена-элемента соответствующей структуры будет другое..
Ведь логично?


Цитата (Guinness @  28.8.2014,  09:51 findReferencedText)
Не самая здравая, особенно, если приложение достаточно большое, и в нём присутствует многопоточность.

Я по этому поводу читал, но не понимал. Как узнать наличие и необходимость многопоточности?
ava
Guinness | 28.08.2014, 14:11 #
Цитата (hoz @  28.8.2014,  14:47 findReferencedText)
Члены-элементы данной структуры. Бывает, что нужны члены-методы структуры или класса. Но члены являются общими для перечня других классов. Значит объект должен быть тот же, верно?
  Ведь, если объект будет другой, то значение члена-элемента соответствующей структуры будет другое..
  Ведь логично?

Логично, но звучит стрёмно. Если это действительно один объект, и он действительно должен быть разделяемым между другими объектами, и никак по другому нельзя осуществить с ним работу, кроме как объявлением его глобальной переменной, то выхода нет. Но я бы рекомендовал ещё разок подумать, может удастся как-то перепроектировать.
Цитата (hoz @  28.8.2014,  14:47 findReferencedText)
Я по этому поводу читал, но не понимал. Как узнать наличие и необходимость многопоточности? 

Вопрос интересный, я вряд ли смогу дать грамотный ответ на него. Узнать наличие можно посмотрев по коду запускаются ли где-то потоки. Или используются ли где-то сторонние классы, которые могут асинхронно вызывать Ваш код. Нужна ли параллельность? Это каждый решает сам. К примеру, GUI и бизнес-процессы, как правило, работают в разных потоках, дабы GUI не подвисал.
ava
baldman88 | 28.08.2014, 15:05 #
Про Singleton уже написали. Посмотрите еще на статические классы -- по смыслу они ближе всего к вашей "проблемной" структуре smile 
ava
hoz | 28.08.2014, 21:51 #
 Ну а что тут удивительного то? Например, тип intdouble или string используются везде... и они глобальны. Ведь так? И никто не говорит, что это не хорошо. А когда другие глобальные переменные, то почему-то не хороший тон... Логика в чём?
ava
baldman88 | 29.08.2014, 00:27 #
Создается впечатление, что Вы путаете теплое с мягким. Что Вы понимаете под глобальными переменными? В ООП глобальные переменные -- признак плохого тона, даже если они встроенных типов.
ava
Guinness | 29.08.2014, 06:59 #
Цитата (hoz @  28.8.2014,  22:51 findReferencedText)
 Ну а что тут удивительного то? Например, тип int, double или string используются везде... и они глобальны.

Цитата (Guinness @  28.8.2014,  10:51 findReferencedText)
Так используется структура или один и тот же объект?

Неспроста я задал этот вопрос. Класс/структура и объект - две разные вещи.
ava
sQu1rr | 29.08.2014, 09:54 #

// #1
// Просто хедер со структурой со статичными методами, будет рабртать везде без особого напряга
struct StaticStruct {
    static int method1() const { return member; }
    static void method2(int m) { member = m }
    static int member;
};
...
StaticStruct::method2(3)
int y = StaticStruct::method1();
// # 2
// Просто хедер со структурой, включайте куда хотите, плодите объекты и вызывайте их методы
struct SomeStruct {
    int method1() const { return member; }
    void method2(int m) { member = m }
    int member;
};
...
SomeStruct x;
x.method2(3)
int y = x.method1();
// #3 : #2
// Второй вариант, но синглтон, имеет метод который возвращает один и тот же объект
    static SomeStruct & getInstance() const { static SomeStruct x; return x; }
...
SomeStruct::getInstance().method2(3);
...
// #4
// можно веселиться с экстернами

pick one что бы все были в теме о чем идет речь
PS не стоит принимать мой код в серьез, писал левой задней ногой
ava
hoz | 30.08.2014, 14:50 #
Цитата (baldman88 @  29.8.2014,  00:27 findReferencedText)
Создается впечатление, что Вы путаете теплое с мягким. Что Вы понимаете под глобальными переменными? В ООП глобальные переменные -- признак плохого тона, даже если они встроенных типов. 

Да, я не верно выразился. Я имел ввиду объекты, которые "видят" все классы. Они ведь являются глобальными, если с ними работают, если и не все, но большинство классов, так? Это ж как переменные..
Дабы объяснить ситуацию, опишу что нужно.

Есть та же структура (одна из них), члены-элементы и члены-методы которой используются различными классами. По крайне мере такая возможность должна быть. Причём другие классы должны работать не с разными копиями членов-элементов объектов интересующей нас структуры, а именно с этой! Т.к. в этой копии объекта структуры хранятся важные данные, которые, скажем так, нет необходимость пересчитывать каждый раз, а только по необходимости. И все классы этот момент по-своему контролируют. Понятно изъясняюсь?
Вот такой вот момент.
В начале написания первого кода посредством ООП я после структур и классов сразу создавал объект, как показал sQu1rr.
Но правильно ли это? Подумав, я понял, что признаком хорошего тона программирования это не является, т.к. не все объекты, и не все классы используются всегда.
Вот решил переписать то, что есть на хороший тон.
ava
hoz | 30.08.2014, 23:09 #
Цитата (Guinness @  29.8.2014,  06:59 findReferencedText)
Неспроста я задал этот вопрос. Класс/структура и объект - две разные вещи. 

Один и тот же объект соответствующей структуры.
ava
hoz | 31.08.2014, 13:56 #
Цитата (sQu1rr @  29.8.2014,  09:54 findReferencedText)
// #1

// Просто хедер со структурой со статичными методами, будет рабртать везде без особого напряга

struct StaticStruct {
  static int method1() const { return member; }
  static void method2(int m) { member = m }
  static int member;

};

...

StaticStruct::method2(3)

int y = StaticStruct::method1();

По ходу в данном коде в поле:

static int method1() const { return member; }

модификатор доступа static лишний. Т.к. данный метод только возвращает, а не преобразовывает статический член-элемент static int member. Так?
Я так понимаю, в данной строке:

StaticStruct::method2(3)

создаётся статический метод.
А в этой как понимать присвоение к y метода method2() ?
ava
hoz | 31.08.2014, 14:14 #
Цитата (sQu1rr @  29.8.2014,  09:54 findReferencedText)
// # 2

// Просто хедер со структурой, включайте куда хотите, плодите объекты и вызывайте их методы

struct SomeStruct {
  int method1() const { return member; }
  void method2(int m) { member = m }
  int member;

};

...

SomeStruct x;

x.method2(3)

int y = x.method1();

А статическим делать не нужно разве члены? Странно как-то..
ava
baldman88 | 01.09.2014, 09:27 #
Цитата (hoz @  31.8.2014,  13:56 findReferencedText)
По ходу в данном коде в поле:
static int method1() const { return member; }


модификатор доступа static лишний. Т.к. данный метод только возвращает, а не преобразовывает статический член-элемент static int member. Так?

Нет не лишний. К статическому полю может обращаться только статический метод. А вот модификатор const лишний.
Модификатор static позволяет сделать метод либо поле общим для всех экземпляров (глобальным, если можно так сказать, хотя аналогия неудачная, но все же).
ava
hoz | 01.09.2014, 13:59 #
Цитата (baldman88 @  1.9.2014,  09:27 findReferencedText)
А вот модификатор const лишний.

Это ещё почему? Ведь данная конструкция является геттером, а значит, она не изменяется ни одно поле.

И вообще, зачем тут геттер, если это структура, а не класс? В структуре же все члены являются открытыми, а значит к ним можно обращаться напрямую минуя геттеры и сеттеры?
ava
sQu1rr | 01.09.2014, 19:58 #
Цитата (baldman88 @  1.9.2014,  09:27 findReferencedText)
 А вот модификатор const лишний.

Цитата (sQu1rr @  29.8.2014,  09:54 findReferencedText)
PS не стоит принимать мой код в серьез, писал левой задней ногой

Еще и упустил объявление статичного члена вне класса, так что да :)

Цитата (hoz @  31.8.2014,  13:56 findReferencedText)
А в этой как понимать присвоение к y метода method2() тут?

щито?
int y = someClass.getY(); // вы тут тоже присваеваете метод?
ClassButNotInstance::staticMethod() - это вызов статичного метода класса, а не его инстанции.


Цитата (hoz @  1.9.2014,  13:59 findReferencedText)
 Ведь данная конструкция является геттером, а значит, она не изменяется ни одно поле.

Const "как бы делает" this константным. тоесть обращение к членам класса (return y) что есть (return this->y) будет read-only. В статичных методах нет this, так как они не привязаны к определенной инстанции.
ava
baldman88 | 02.09.2014, 09:27 #
Цитата (baldman88 @  1.9.2014,  09:27 findReferencedText)
А вот модификатор const лишний.

Цитата (hoz @  1.9.2014,  13:59 findReferencedText)
Это ещё почему?

Цитата (sQu1rr @  1.9.2014,  19:58 findReferencedText)
Const "как бы делает" this константным. тоесть обращение к членам класса (return y) что есть (return this->y) будет read-only. В статичных методах нет this, так как они не привязаны к определенной инстанции.
ava
Lukkoye | 08.09.2014, 12:01 #
Цитата (hoz @  1.9.2014,  13:59 findReferencedText)
Это ещё почему? Ведь данная конструкция является геттером, а значит, она не изменяется ни одно поле.



И вообще, зачем тут геттер, если это структура, а не класс? В структуре же все члены являются открытыми, а значит к ним можно обращаться напрямую минуя геттеры и сеттеры? 



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


Резюмируя: константными могут быть только простые методы класса. Но не статические.
Зарегистрируйтесь или войдите, чтобы написать.
Фирма дня
Вы также можете добавить свою фирму в каталог IT-фирм, и публиковать статьи, новости, вакансии и другую информацию от имени фирмы.
Подробнее
Участники
advanced
Отправить