Форум программистов, компьютерный форум, киберфорум
Наши страницы

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

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

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

18.04.2013, 11:28. Просмотров 1115. Ответов 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 - нельзя?
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
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( );

24
StasGamilton
18.04.2013, 17:31     Где создавать объекты классов?
  #16

Не по теме:

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

0
taras atavin
3570 / 1754 / 91
Регистрация: 24.11.2009
Сообщений: 27,567
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 Посмотреть сообщение
Общая рекомендация — чем более закрытая область используется, тем лучше. Е
Бредятина. Если ты создал объект в закрытой области, а потом одумался и решил, что он нужен за её пределами, то придётся переделывать. И не один раз, а сотни. Любая переменная и объект в том числе должен быть объявлен в той области видимости, где он может быть нужен, не ниже, но и не выше даже на один уровень. И реально создан не раньше и не позже, чем это на самом деле нужно.
1
dimkaok
1 / 1 / 0
Регистрация: 06.03.2013
Сообщений: 128
18.04.2013, 17:44  [ТС] #18
Цитата Сообщение от taras atavin Посмотреть сообщение
Объект нельзя разместить внутри его класса, рекурсия типов запрещена, исключение сделано только для указателей.
Да не, я имел ввиду не внутри своего класса, а внутри класса, в котором этот объект вызывается.

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

Добавлено через 2 минуты
Цитата Сообщение от dimkaok Посмотреть сообщение
А вообще допускается-ли создание объекта в приватной части класса и работа с ним через get/set?
То есть это работает, но это широко распространено?
Да, это один из принципов ООП — инкапсуляция.
0
taras atavin
3570 / 1754 / 91
Регистрация: 24.11.2009
Сообщений: 27,567
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 символ исправлять из-за областей видимости, не смотря на то, что хватает объектов в глобале с пабликом на все члены.
0
shuffle
19 / 19 / 1
Регистрация: 30.03.2013
Сообщений: 35
18.04.2013, 19:08 #21
Цитата Сообщение от taras atavin Посмотреть сообщение
Дело не в том, что к нему нельзя достучаться, а в том, что потом ты запутаешься, что у тебя где валяется.
Обязательно запутаетесь, особенно, если писать код сдуру. Ваш первоначальный тезис — объявлять типы и объекты там, где они будут использоваться, он замечательный. Но польза от него такая же, как от совета не допускать ошибок. Программист будет ошибаться, и он будет писать объявления не там, где нужно. Рекомендуемая стратегия по уменьшению области видимости/доступа вытекает из необходимости уменьшения связности программы. Держать в голове взаимосвязи типов и объектов в программе существенно сложнее найти «потерявшуюся» переменную.
0
taras atavin
3570 / 1754 / 91
Регистрация: 24.11.2009
Сообщений: 27,567
18.04.2013, 19:14 #22
Объект - такая же переменная. И связей между целыми объектами даже в суперкривом проекте меньше, чем в не ООП проекте на аналогичную тему скалярных переменных, которые могут потеряться. Кроме того, связи эти вытекают из логики проекта, ассоциируются в мозгу и держатся лучше, чем названия пальцев, не говоря про скалярные переменные. В человеческой памяти не противоречивая структура связей между объектами вся - одна единица хранения. Один гигантский байт. И забыть его суперсложно, он для этого слишком громоздок. Если же связи до такой степени не ассоциируются, если каждое поле само по себе, то или проект кривой, или бросай программирование.
0
shuffle
19 / 19 / 1
Регистрация: 30.03.2013
Сообщений: 35
18.04.2013, 19:24 #23
Цитата Сообщение от taras atavin Посмотреть сообщение
Проблема таких отвлечённых рекомендаций в том, что всегда найдётся псих, который посоветует всё в глобал вытащить и "обоснует" это тем, что всего лишь один объект не является частью другого.
Рекомендация это не правило, а из ее обоснования должно приходить понимание ее применимости. Можно давать советы «всегда думать головой» и «писать код без ошибок», но они бесполезны.

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

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

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

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

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

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

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


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

Или воспользуйтесь поиском по форуму:
25
Ответ Создать тему
Опции темы

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