Форум программистов, компьютерный форум, киберфорум
С++ для начинающих
Войти
Регистрация
Восстановить пароль
Карта форума Темы раздела Блоги Сообщество Поиск Заказать работу  
 
 
Рейтинг 4.57/7: Рейтинг темы: голосов - 7, средняя оценка - 4.57
7 / 7 / 2
Регистрация: 19.06.2013
Сообщений: 174
1

Чем может быть чревато создание в классе адреса на другой класс

09.06.2014, 02:15. Показов 1265. Ответов 20
Метки нет (Все метки)

Author24 — интернет-сервис помощи студентам
Всем привет!
Я решил не заморачиваться с наследованием, так как у меня каждый класс использует только свои узкоспециализированные функции. А вот некоторые данные из класса все равно таскать приходится.
Таким образом, у меня возникла вот такая, можно сказать, иерархия:

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
class Object //Хранит в себе всю информацию о любом объекте
{
public:
float o1;
float o2;
float o3;
Object() //Конструктор
{
o1 = 1;
o2 = 2;
o3 = 3;
}
~Object(){} //Деструктор
void ObjectFunc1(){} //Функция 1
void ObjectFunc2(){} //Функция 2
};
 
class Paint //Клас Paint не наследует класс Object, тем не менее имеет внутри себя один экземпляр класса Object
{
public:
Object* MyObject; //Адрес экземпляра класса Object
Paint(Object* fObject) //Конструктор
{
MyObject = fObject; //Копирование в переменную класса Paint адреса уже существующего экземпляра Object
}
~Paint(){} //Деструктор
void PaintFunc1(){} //Функции-члены Paint
void PaintFunc2(){} 
};
 
void WinMain()
{
Object *MyObject = new Object;
Paint   *MyPaint   = new Paint(MyObject);
 
//Используем Paint как хотим
 
delete Object;
delete Paint1;
}
Вот так у меня это реализовано.
Вопрос в том, есть ли в такой реализации подводные камни, если есть, то какие??
Буду благодарен за любые предупреждения и мысли по этому поводу.
Лично мне кажется, что никакой опасности нет, тем не менее чутье ноет о том, что здесь не совсем все так просто как кажется...
0
Лучшие ответы (1)
Programming
Эксперт
94731 / 64177 / 26122
Регистрация: 12.04.2006
Сообщений: 116,782
09.06.2014, 02:15
Ответы с готовыми решениями:

наследование в классе нескольких функций из другого или как добавить функцию находящуюся в классе в другой класс
есть класс. есть второй класс. как добавить функцию находящуюся в классе в другой класс(второй) при...

Сколько может быть конструкторов в классе?
Только один или можно больше?

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

Может ли индексатор быть переопределен в дочернем классе
A) Да, но только один раз B) Нет C) Да D) Да, но только для индексатора без параметров

20
347 / 292 / 37
Регистрация: 23.03.2012
Сообщений: 838
09.06.2014, 02:17 2
Голые указатели всегда опасны.
0
7 / 7 / 2
Регистрация: 19.06.2013
Сообщений: 174
09.06.2014, 02:25  [ТС] 3
У меня структура даже сложнее чем я указал:
есть еще класс stage, который имеет в себе Paint и похожие по структуре на Paint классы и манипулирует ими тем же способом. Я планировал сделать ЕЩЕ класс, который будет манипулировать stage'ами, но у меня полезли какие-то настолько странные ошибки, что я отказался от идеи так глубоко залезать по классам и сделал просто функцию.
Тем не менее такая сложная иерархия классов осталась (получается, что один класс имеет доступ к экземплярам двух классов, которые еще и создан один из другого).
0
Комп_Оратор)
Эксперт по математике/физике
8950 / 4704 / 629
Регистрация: 04.12.2011
Сообщений: 13,999
Записей в блоге: 16
09.06.2014, 03:00 4
Divergence, использование объектов классов или указателей на объекты классов в качестве полей классов это нормально. Если говорить об указателях, то это чуть более трудоёмко чем просто использовать сам объект. Разница почти та же, что и при использовании переменной указателя на стеке, но тяжелее то, что конструкторов не один и везде нужно побеспокоиться о инициализации указателя. То есть нужно выделить память, чем-то заполнить, а в деструкторе удалить.
В Вашем конструкторе копируется указатель и Вы не можете знать указывает он на что-то разумное или нет. Обычно в таких случаях делают иначе. Но сначала нужно написать конструктор без параметров и или закрыть его (тогда он может быть пустой) или выделить в нём память под объект и заселить её объектом по умолчанию. Закрывать - прём узкий. Это значит, что контейнеры STL использовать не выйдет, например.
Написав открытые конструкторы Вы будете уверены, что как бы не создавался экземпляр, он будет инициализирован. А в конструкторе копирования тоже нужно бы выделить память и скопировать в неё объект из оригинала почленно. В деструкторе удалить. Тут лучше ничего не делать руками.
1
7 / 7 / 2
Регистрация: 19.06.2013
Сообщений: 174
09.06.2014, 03:16  [ТС] 5
Цитата Сообщение от IGPIGP Посмотреть сообщение
Divergence, использование объектов классов или указателей на объекты классов в качестве полей классов это нормально. Если говорить об указателях, то это чуть более трудоёмко чем просто использовать сам объект. Разница почти та же, что и при использовании переменной указателя на стеке, но тяжелее то, что конструкторов не один и везде нужно побеспокоиться о инициализации указателя. То есть нужно выделить память, чем-то заполнить, а в деструкторе удалить.
В Вашем конструкторе копируется указатель и Вы не можете знать указывает он на что-то разумное или нет. Обычно в таких случаях делают иначе. Но сначала нужно написать конструктор без параметров и или закрыть его (тогда он может быть пустой) или выделить в нём память под объект и заселить её объектом по умолчанию. Закрывать - прём узкий. Это значит, что контейнеры STL использовать не выйдет, например.
Написав открытые конструкторы Вы будете уверены, что как бы не создавался экземпляр, он будет инициализирован. А в конструкторе копирования тоже нужно бы выделить память и скопировать в неё объект из оригинала почленно. В деструкторе удалить. Тут лучше ничего не делать руками.
IGPIGP, спасибо за ответ!
Если честно, я не очень понимаю эти опасения по поводу того, что указатель может не указывать на существующую область памяти... у меня в коде сначала выделяется память, только затем в новый класс передается указатель. В случае такого грамотного подхода (когда ничего не забыто) опасности никакой нет?
Или все же могут быть косяки?
Например, я смутно предполагаю ситуацию, что в какой-то момент вызовется деструктор, который освободит память, на которую у меня несколько указателей по определению... Соответственно, несколько указателей будут указывать на пустоту. Однако, логика программы такова, что жизнь одного класса без другого просто не имеет смысла, поэтому уничтожаться они будут строго один за другим до самого конца. Остаются ли какие-то опасности при такой ситуации?
0
347 / 292 / 37
Регистрация: 23.03.2012
Сообщений: 838
09.06.2014, 03:20 6
Лучший ответ Сообщение было отмечено Divergence как решение

Решение

Цитата Сообщение от Divergence Посмотреть сообщение
IGPIGP, спасибо за ответ!
Если честно, я не очень понимаю эти опасения по поводу того, что указатель может не указывать на существующую область памяти... у меня в коде сначала выделяется память, только затем в новый класс передается указатель. В случае такого грамотного подхода (когда ничего не забыто) опасности никакой нет?
Или все же могут быть косяки?
Например, я смутно предполагаю ситуацию, что в какой-то момент вызовется деструктор, который освободит память, на которую у меня несколько указателей по определению... Соответственно, несколько указателей будут указывать на пустоту. Однако, логика программы такова, что жизнь одного класса без другого просто не имеет смысла, поэтому уничтожаться они будут строго один за другим до самого конца. Остаются ли какие-то опасности при такой ситуации?
Зачем тогда создавать объект снаружи и передавать указатель на него? Почему бы не создать его внутри?
1
Комп_Оратор)
Эксперт по математике/физике
8950 / 4704 / 629
Регистрация: 04.12.2011
Сообщений: 13,999
Записей в блоге: 16
09.06.2014, 03:22 7
Цитата Сообщение от Divergence Посмотреть сообщение
В случае такого грамотного подхода (когда ничего не забыто) опасности никакой нет?
В случае такого грамотного подхода, само понятие опасности теряет смысл.
Какая может быть опасность для человека, которого не испугать? А что мешает написать конструктор по умолчанию, конструктор копии, деструктор и перегрузить оператор присваивания?
0
7 / 7 / 2
Регистрация: 19.06.2013
Сообщений: 174
09.06.2014, 03:30  [ТС] 8
Цитата Сообщение от Nekto Посмотреть сообщение
Зачем тогда создавать объект снаружи и передавать указатель на него? Почему бы не создать его внутри?
Спасибо за идею! Действительно, я подумаю об этом. Небольшие трудности создает только то, что в дальнейшем, мне может потребоваться один класс отдельно от другого для каких-то еще не придуманных сейчас целей. Это удерживает. Но скорее всего я последую совету

Добавлено через 5 минут
Цитата Сообщение от IGPIGP Посмотреть сообщение
А что мешает написать конструктор по умолчанию, конструктор копии, деструктор и перегрузить оператор присваивания?
Просто не могу заставить себя делать что-то сложное, когда можно сделать просто. Я сделал просто и понятно для себя, без лишних наворотов. Если бы я точно понимал какие плюсы мне даст вся эта перегрузка и куча конструкторов, и я бы эти плюсы посчитал существенными, то конечно сделал бы так.
Именно потому, я и написал вопрос на форуме: я сделал просто, хотя обычно люди делают сложно, и причин для такой сложности я не увидел. Вот и хочу послушать аргументы в пользу сложного подхода.
Но пока, на такую сложную модель переходить я не переубедился
0
Комп_Оратор)
Эксперт по математике/физике
8950 / 4704 / 629
Регистрация: 04.12.2011
Сообщений: 13,999
Записей в блоге: 16
09.06.2014, 03:35 9
Цитата Сообщение от Nekto Посмотреть сообщение
Зачем тогда создавать объект снаружи и передавать указатель на него? Почему бы не создать его внутри?
Конечно!
Цитата Сообщение от IGPIGP Посмотреть сообщение
сначала нужно написать конструктор без параметров и ... выделить в нём память под объект и заселить её объектом по умолчанию.
Ведь при попытке объявить такой объект как сейчас на стеке нужно будет каждый раз инициализировать его руками. А заполнить вектор такими объектами? Лучше пусть это делает конструктор, а прямой доступ к указателю снаружи и закрыть можно бы.
0
Каратель
Эксперт С++
6609 / 4028 / 401
Регистрация: 26.03.2010
Сообщений: 9,273
Записей в блоге: 1
09.06.2014, 12:21 10
Цитата Сообщение от Divergence Посмотреть сообщение
Вопрос в том, есть ли в такой реализации подводные камни, если есть, то какие??
C++
1
Paint paint(0);
1
:)
Эксперт С++
4773 / 3267 / 497
Регистрация: 19.02.2013
Сообщений: 9,046
09.06.2014, 14:07 11
Divergence, удалять объекты надо в порядке обратном их созданию. Т.е. сначала MyPaint, потом MyObject. А вообще, см. что такое "умные" указатели.
Цитата Сообщение от Jupiter Посмотреть сообщение
C++
1
Paint paint(0);
По приведенному ТС коду, проблемы с нулевым указателем нет.
0
Jupiter
09.06.2014, 14:33
  #12

Не по теме:

Цитата Сообщение от Tulosba Посмотреть сообщение
По приведенному ТС коду, проблемы с нулевым указателем нет.
додо, конечно же у ТС все методы пустые и просто так хранится указатель

0
:)
Эксперт С++
4773 / 3267 / 497
Регистрация: 19.02.2013
Сообщений: 9,046
09.06.2014, 15:27 13
Jupiter, додомывать можно сколько угодно. Может у него там и if'ами всё обвешано с проверкой на нуль. Но чего не показано, того не показано.
0
Jupiter
09.06.2014, 15:34
  #14

Не по теме:

Цитата Сообщение от Tulosba Посмотреть сообщение
сколько угодно
Цитата Сообщение от Tulosba Посмотреть сообщение
нельзя идти на поводу у ТС. Надо жесткой хваткой взять его и сказать: "что же ты делаешь! Так нельзя.Потому что: раз, два и три".
занавес...

0
:)
Эксперт С++
4773 / 3267 / 497
Регистрация: 19.02.2013
Сообщений: 9,046
09.06.2014, 15:38 15
Jupiter, не вижу связи. Одно дело, видеть кривой код и критиковать его. И совсем другое - критиковать по результатам своих фантазий.
0
7 / 7 / 2
Регистрация: 19.06.2013
Сообщений: 174
09.06.2014, 23:33  [ТС] 16
Ребят, а что такое ТС код?
Цитата Сообщение от Jupiter Посмотреть сообщение
нельзя идти на поводу у ТС
???
Цитата Сообщение от Jupiter Посмотреть сообщение
Надо жесткой хваткой взять его и сказать: "что же ты делаешь! Так нельзя.Потому что: раз, два и три
Кого его? оО
0
347 / 292 / 37
Регистрация: 23.03.2012
Сообщений: 838
09.06.2014, 23:36 17
Цитата Сообщение от Divergence Посмотреть сообщение
Ребят, а что такое ТС код?
С подключением к интернету. ТС = топикстартер.
0
7 / 7 / 2
Регистрация: 19.06.2013
Сообщений: 174
09.06.2014, 23:53  [ТС] 18
Цитата Сообщение от Nekto Посмотреть сообщение
С подключением к интернету. ТС = топикстартер.

Цитата Сообщение от Divergence Посмотреть сообщение
Надо жесткой хваткой взять его и сказать: "что же ты делаешь! Так нельзя.Потому что: раз, два и три
Пока что я увидел опасность только в кодере, который может ошибиться. Другие аргументы меня не убедили.
Как я понял, народ настаивает на создании еще одного пустого конструктора?
А вот зачем сюда нужна перегрузка операторов - вот совсем не понял.

Добавлено через 13 минут
Цитата Сообщение от Divergence Посмотреть сообщение
Зачем тогда создавать объект снаружи и передавать указатель на него? Почему бы не создать его внутри?
Вы были абсолютно правы. Я сейчас собрал простенький проект с тестовыми классами (чтобы не морочиться с большим кол-вом кода). Если ссылку на один и тот же класс используют два класса (а у меня именно такая ситуация и назревала), то деструктор выкидывает в ошибку, так как я пытаюсь удалить пустоту.
Вот и ответ на мой вопрос... нельзя передавать в класс просто ссылки на классы (особенно если они инициализированы в динамической памяти). Нужно работать с объектами других классов только внутри самого класса.
0
347 / 292 / 37
Регистрация: 23.03.2012
Сообщений: 838
10.06.2014, 00:44 19
Цитата Сообщение от Divergence Посмотреть сообщение
Нужно работать с объектами других классов только внутри самого класса.
Для этого придумали умные указатели. std::shared_ptr, думаю, подойдет для данного случая.
2
7 / 7 / 2
Регистрация: 19.06.2013
Сообщений: 174
10.06.2014, 01:38  [ТС] 20
Цитата Сообщение от Nekto Посмотреть сообщение
Для этого придумали умные указатели. std::shared_ptr, думаю, подойдет для данного случая.
Спасибо! Почитаю об этом в ближайшее время!)
0
10.06.2014, 01:38
IT_Exp
Эксперт
87844 / 49110 / 22898
Регистрация: 17.06.2006
Сообщений: 92,604
10.06.2014, 01:38
Помогаю со студенческими работами здесь

5 короткий сигналов биос, может ли дело быть в чем то другом чем в процессоре?
Комп врубается однако он никак не реагирует на мышь и клавиатуру, даже заходит во вход в Windows,...

Определите,может ли этот IP-адреса быть назначен узлом
Определите,может ли этот IP-адреса быть назначен узлом. Если нет то объясните, почему IP-адрес не...

Сколько в классе может быть объявлено не статических конструкторов по умолчанию?
Вроде бы неограниченное количество, но не уверен точно.

Стоят планки с частотой выше, чем поддерживает чипсет. Чем чревато?
Доброго дня. Недавно по случаю заглянул в AIDA64, поинтересоваться, какую оперативку поддерживает...


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

Или воспользуйтесь поиском по форуму:
20
Ответ Создать тему
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2024, CyberForum.ru