Форум программистов, компьютерный форум CyberForum.ru

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

Войти
Регистрация
Восстановить пароль
 
 
dimkaok
1 / 1 / 0
Регистрация: 06.03.2013
Сообщений: 128
#1

Где создавать объекты классов? - C++

18.04.2013, 11:28. Просмотров 1060. Ответов 24
Метки нет (Все метки)

Здравствуйте. Подскажите, если есть много классов, объявленных в заголовочных файлах,
а определенных в *.cpp - файлах, и для каждого класса создается объект, где эти объекты правильно создавать.
Я создаю их там где они оказываются нужны в первый раз. Например:

C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
// A.cpp
#include "B.cpp"
class A {
    B objB;
};
 
// B.cpp
#include "A.cpp"
#include "C.cpp"
class B {
    A objA;
    C objC;
};
 
//C.cpp
#include "B.cpp"
class C {
    B objB;
};
А то у меня создание объектов разбросано по всей программе,
может это нужно делать где-то в одном месте? (обычно подключаю *.h - файлы, а не *.cpp, как здесь,
не стал писать, чтоб упростить пример)

И правильно-ли, что объекты нужно создавать только в *.cpp - файлах, а в *.h - нельзя?
Similar
Эксперт
41792 / 34177 / 6122
Регистрация: 12.04.2006
Сообщений: 57,940
18.04.2013, 11:28
Здравствуйте! Я подобрал для вас темы с ответами на вопрос Где создавать объекты классов? (C++):

Считается ли хорошим тоном создавать объекты классов в области глобальных переменных - C++
Считается ли хорошим тоном создавать объекты классов в области глобальных переменных? class FX { ........ ......... };

Стек или куча: как "правильно" создавать объекты классов? - C++
У меня несколько странновато-ламерский вопрос, но ведь в том и смысл: чтобы таких вопросов не осталось, на них один фиг сначала нужно...

Преобразования объектов классов в объекты других классов - C++
Задача типа обмен валют. Нужно конвертировать старый фунт стерлинг(фунт, шиллинг и пенсы) в доллары и обратно, по курсу 1 фунт = 50...

Как создавать в цикле разные объекты одной структуры? - C++
Допустим есть структура которая представляет из себя ячейку которая хранит данные по координатам X Y Z и некоторые свойства этой ячейки. ...

При выделении памяти через malloc, как создавать объекты ? - C++
Выделяю память через malloc под 4 объекта, как их создать ? myClass * ptr = (myClass*) malloc(sizeof(myClass)*4); for(int i = 0;...

Указатель на объекты и члены классов - C++
class AA { public: void Start( ); }; class BB { public: void Start( );

Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
StasGamilton
18.04.2013, 17:31     Где создавать объекты классов?
  #16

Не по теме:

Цитата Сообщение от taras atavin Посмотреть сообщение
Ещё один такой же.
Непонял. Это в каком смылсе?

taras atavin
Ушёл с форума.
3569 / 1752 / 91
Регистрация: 24.11.2009
Сообщений: 27,619
18.04.2013, 17:32 #17
C++
1
2
3
4
5
6
7
8
9
10
11
class A
{
};
 
A a; // объект класса A
class B
{
 A ba; // объект класса A, но член класса B. Такой объект называется агрегированным. Так следует делать тогда и только тогда, когда объект одного класса является частью объекта другого класса
};
 
B b; // Объект класса B, содержащий агрегированный объект ba класса A. Сам b - агрегат.
Цитата Сообщение от shuffle Посмотреть сообщение
Общая рекомендация — чем более закрытая область используется, тем лучше. Е
Бредятина. Если ты создал объект в закрытой области, а потом одумался и решил, что он нужен за её пределами, то придётся переделывать. И не один раз, а сотни. Любая переменная и объект в том числе должен быть объявлен в той области видимости, где он может быть нужен, не ниже, но и не выше даже на один уровень. И реально создан не раньше и не позже, чем это на самом деле нужно.
dimkaok
1 / 1 / 0
Регистрация: 06.03.2013
Сообщений: 128
18.04.2013, 17:44  [ТС] #18
Цитата Сообщение от taras atavin Посмотреть сообщение
Объект нельзя разместить внутри его класса, рекурсия типов запрещена, исключение сделано только для указателей.
Да не, я имел ввиду не внутри своего класса, а внутри класса, в котором этот объект вызывается.

А вообще допускается-ли создание объекта в приватной части класса и работа с ним через get/set?
То есть это работает, но это широко распространено?
shuffle
19 / 19 / 1
Регистрация: 30.03.2013
Сообщений: 35
18.04.2013, 17:51 #19
Цитата Сообщение от taras atavin Посмотреть сообщение
Если ты создал объект в закрытой области, а потом одумался и решил, что он нужен за её пределами, то придётся переделывать.
Или не переделывать, а предоставить к нему интерфейс доступа. Заменить private на public — вопрос 5 символов. Обратную замену сделать уже не так просто — придется рефакторить все места, где используется этот закрытый член (как вы и сказали, «не один раз, а сотни»). Чем меньше данных в открытом интерфейсе, тем меньше потенциальная связность объектов, тем более гибкая и автономная структура программы. Отсюда и рекомендация.

Добавлено через 2 минуты
Цитата Сообщение от dimkaok Посмотреть сообщение
А вообще допускается-ли создание объекта в приватной части класса и работа с ним через get/set?
То есть это работает, но это широко распространено?
Да, это один из принципов ООП — инкапсуляция.
taras atavin
Ушёл с форума.
3569 / 1752 / 91
Регистрация: 24.11.2009
Сообщений: 27,619
18.04.2013, 19:07 #20
Цитата Сообщение от shuffle Посмотреть сообщение
Или не переделывать, а предоставить к нему интерфейс доступа. Заменить private на public — вопрос 5 символов.
И? Дело не в том, что к нему нельзя достучаться, а в том, что потом ты запутаешься, что у тебя где валяется. Потому что не понимаешь, где оно должно лежать, а можешь только слушать на эту тему чужие советы. И public работает только с классами. А если ты умудрился в функцию объект запихать? Хорошо, если обоснованно, тогда ни в коем случае не вытаскивай, противоположная ошибка так же плоха. А если сдуру?

Добавлено через 9 минут
Цитата Сообщение от dimkaok Посмотреть сообщение
Да не, я имел ввиду не внутри своего класса, а внутри класса, в котором этот объект вызывается.
А вообще допускается-ли создание объекта в приватной части класса и работа с ним через get/set?
То есть это работает, но это широко распространено?
Агрегировать можно куда угодно, а часто агрегированные объекты и должны быть приватными. Думать надо, когда декларируешь и когда фактически создаёшь объекты. Думать и проектировать. Да и вообще при программировании. И решать в каждом конкретном случае, стоит ли прятать объект внутри другого класса. Часто стоит, а наследование не всегда уместно. Но вытекать этот приват должен из конкретных потребностей задачи, а не из абстрактнейших рекомендаций из всех возможных.
Цитата Сообщение от shuffle Посмотреть сообщение
придется рефакторить все места, где используется этот закрытый член (как вы и сказали, «не один раз, а сотни»).
Я имел ввиду совсем не это. 1 000 000 исправлений по всей проге в связи с изменнием видимости - это одна большая переделка. А вот передумать ещё раз и снова прятать то, что только что вытащил - это ещё большая глупость. Но когда исходишь только из посторонних советов на все случаи жизни, то передумывать можешь каждую минуту до срока сдачи и в итоге все завалить.

Добавлено через 9 минут
Цитата Сообщение от shuffle Посмотреть сообщение
Заменить private на public — вопрос 5 символов. Обратную замену сделать уже не так просто — придется рефакторить все места, где используется этот закрытый член (как вы и сказали, «не один раз, а сотни»). Чем меньше данных в открытом интерфейсе, тем меньше потенциальная связность объектов, тем более гибкая и автономная структура программы. Отсюда и рекомендация.
Проблема таких отвлечённых рекомендаций в том, что всегда найдётся псих, который посоветует всё в глобал вытащить и "обоснует" это тем, что всего лишь один объект не является частью другого. Мне не надо и 1 символ исправлять из-за областей видимости, не смотря на то, что хватает объектов в глобале с пабликом на все члены.
shuffle
19 / 19 / 1
Регистрация: 30.03.2013
Сообщений: 35
18.04.2013, 19:08 #21
Цитата Сообщение от taras atavin Посмотреть сообщение
Дело не в том, что к нему нельзя достучаться, а в том, что потом ты запутаешься, что у тебя где валяется.
Обязательно запутаетесь, особенно, если писать код сдуру. Ваш первоначальный тезис — объявлять типы и объекты там, где они будут использоваться, он замечательный. Но польза от него такая же, как от совета не допускать ошибок. Программист будет ошибаться, и он будет писать объявления не там, где нужно. Рекомендуемая стратегия по уменьшению области видимости/доступа вытекает из необходимости уменьшения связности программы. Держать в голове взаимосвязи типов и объектов в программе существенно сложнее найти «потерявшуюся» переменную.
taras atavin
Ушёл с форума.
3569 / 1752 / 91
Регистрация: 24.11.2009
Сообщений: 27,619
18.04.2013, 19:14 #22
Объект - такая же переменная. И связей между целыми объектами даже в суперкривом проекте меньше, чем в не ООП проекте на аналогичную тему скалярных переменных, которые могут потеряться. Кроме того, связи эти вытекают из логики проекта, ассоциируются в мозгу и держатся лучше, чем названия пальцев, не говоря про скалярные переменные. В человеческой памяти не противоречивая структура связей между объектами вся - одна единица хранения. Один гигантский байт. И забыть его суперсложно, он для этого слишком громоздок. Если же связи до такой степени не ассоциируются, если каждое поле само по себе, то или проект кривой, или бросай программирование.
shuffle
19 / 19 / 1
Регистрация: 30.03.2013
Сообщений: 35
18.04.2013, 19:24 #23
Цитата Сообщение от taras atavin Посмотреть сообщение
Проблема таких отвлечённых рекомендаций в том, что всегда найдётся псих, который посоветует всё в глобал вытащить и "обоснует" это тем, что всего лишь один объект не является частью другого.
Рекомендация это не правило, а из ее обоснования должно приходить понимание ее применимости. Можно давать советы «всегда думать головой» и «писать код без ошибок», но они бесполезны.

Добавлено через 9 минут
Цитата Сообщение от taras atavin Посмотреть сообщение
И связей между целыми объектами даже в суперкривом проекте меньше, чем в не ООП проекте на аналогичную тему скалярных переменных, которые могут потеряться.
Речь не про суперкривые проекты, а про большие проекты. В больших проектах одних типов несравнимо больше, чем можно держать в голове, и конечно, про отдельные переменные речи даже не идет. Высокая связность — единственная проблема, для решения которой вообще придуманы все механизмы ограничения доступа, пространств имен и методик рефакторинга. Для чего бы еще они были нужны, если вы и так пишите все там, где надо?
taras atavin
Ушёл с форума.
3569 / 1752 / 91
Регистрация: 24.11.2009
Сообщений: 27,619
18.04.2013, 20:18 #24
Нельзя даже подумать о строке, не вспомнив, что она состоит из символов. Нельзя подумать об автомобиле и забыть, что двигатель - его часть. И если он у вас валяется отдельно - это плохо. Так же плохо, если цилиндры связаны сразу с булыжниками. А если спрятаны глубоко в двигатель и непосредственно не доступны - хорошо. Потому что снаружи они не нужны. В public вообще уместно выносить только интерфейсы, если член класса - как раз часть интерфейса - выноси в палбоик, не стесняйся. Только зулус способен помыслить о телевизоре, забыв об интерфейсе выбора каналов. Причём, если он в поте лица своего этот интерфейс выбрал, а тем более с ноля придумал, то ещё и во всех подробностях его. Но очень плохо, если телевизор валяется в цилиндре двигателя, как не выкручивайся с пабликом, а такое будет быстро забыто. Весь телевизор лучше или в глобал, или в склад телевизоров. Ну в крайнем случае в склад бытовой техники вообще. Опять таки будет трудно забыть, из чего он состоит. Не возможно забыть, что печь имеет футеровку, а электропечь электроды. Не возможно забыть, что электроприбор имеет такие свойства, как напряжение питания, потребляемый ток, вид тока, а если ток переменный. то ещё и количество фаз и частоту. И от размеров иерархии объектов принципиально ничего не меняется, если структура стройна, забыть её сложно. А рекомендация прятать объект в максимально закрытую область, выполняемая без критического анализа, как раз и выльется в телевизор внутри клапана. И в избыток связей и интерфейсов.

Добавлено через 3 минуты
Цитата Сообщение от shuffle Посмотреть сообщение
Высокая связность — единственная проблема, для решения которой вообще придуманы все механизмы ограничения доступа, пространств имен и методик рефакторинга. Для чего бы еще они были нужны, если вы и так пишите все там, где надо?
Там где надо - это как раз без лишних связей вообще, каждая связь должна быть необходима проекту. Именно это, а не суперпамять, обеспечивает надёжное запоминание связей. В большом, но хорошо продуманном проекте, связей меньше, чем в кривом и не только такого же размера, но часто и меньшего.

Добавлено через 5 минут
А сколько там всего типов - не принципиально. Я свободно ориентируюсь в паре миллионов хорошо связанных строк, но "утону" в пяти криво нагромождённых переменных двух скалярных типов, когда быдлокод и экран то целиком не занимает.
StasGamilton
Эксперт по пяченькам
67 / 67 / 1
Регистрация: 16.08.2011
Сообщений: 258
18.04.2013, 21:16 #25
Цитата Сообщение от taras atavin Посмотреть сообщение
В public вообще уместно выносить только интерфейсы, если член класса - как раз часть интерфейса - выноси в палбоик, не стесняйся
Из своего опыта - если член класса интерфейс - то для него всегда делаю геттеры и сеттеры. Причина проста - доступ к переменным часто может потребовать проверку или какие-либо другие действия. Одно дело если тупо приравниваешь, а другое дело если вызываешь функцию. Если класс геттеры и сеттеры написаны правильно, то переживать не стоит, а если нет - то придется на всякий случай, или в случая появления краха системы, заглядывать внутрь класса. Поэтому переменные лучше инкапсулировать, а наверх выдавать только публичные функции.
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
18.04.2013, 21:16
Привет! Вот еще темы с ответами:

Объекты классов в динамической памяти - C++
Я создаю объект класса в динамической памяти ( например map *obj = new map; ) Вопрос: как сделать трехмерый(или хотя бы двумерный) массив...

Использование классов в С++. Простые объекты. - C++
Задание: Описать объект, включающий заданные поля и методы. Написать программу, которая создает массив объектов и список объектов и...

Файлы и объекты производных классов - C++
Вопрос следующий: имеется два класса, базовый и производный. В файл бинарно записывается объект производного класса через указатель на...

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


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

Или воспользуйтесь поиском по форуму:
Yandex
Объявления
18.04.2013, 21:16
Ответ Создать тему
Опции темы

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