Модераторы: bsa
  

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> Как создавать объекты, поля объекта. 
V
    Опции темы
Хоббит
Дата 6.1.2009, 15:10 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Завсегдатай
Сообщений: 1263
Регистрация: 6.11.2005

Репутация: нет
Всего: 1



Допустим есть класс.
Код

class Cls1 {
public:
  Cls1();
  ~Cls1();
  void method();
}


И второй, класс у которого есть поле типа Cls1
Код

class Cls2 {
public:
  Cls2();
  ~Cls2();

  Cls1 cls1;
}


В этом случае объект cls1 создастся в момент создания объекта Cls2, так как Cls1 имеет конструктор по умолчанию.
Как быть если Cls1 не имеет пустого конструктора, а только конструктор с параметрами, более того, параметр определяется в конструкторе Cls2
Код

class Cls1 {
public:
  Cls1(int param);
  ~Cls1();
  void method();
}


И второй, класс у которого есть поле типа Cls1
Код

class Cls2 {
public:
  Cls2() { int param = 2; Нужно проинициализировать cls1};
  ~Cls2();

  Cls1 cls1;
}


Такой код даже не скомпилируется. 
Какой есть выход? Я так понимаю можно сделать поле cls1 типа Cls1*. И в конструкторе создать объект через new, но его тогда надо будет потом удалить... иначе утечка памяти.
А чтобы его корректно удалить, надо заводить конструктор копий для этого объекта счетчик ссылок. Или использовать безопасные указатели, что тоже не хотелось бы.
PM MAIL   Вверх
Fazil6
Дата 6.1.2009, 15:39 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Завсегдатай
Сообщений: 1653
Регистрация: 3.5.2006
Где: Минск

Репутация: 7
Всего: 60



Цитата(Хоббит @  6.1.2009,  15:10 Найти цитируемый пост)
Как быть если Cls1 не имеет пустого конструктора, а только конструктор с параметрами, более того, параметр определяется в конструкторе Cls2

Слышал когда-нибудь про список инициализации?
Код

class Cls2 {
public:
  Cls2( int param ) : cls1(param) { };
  ~Cls2();
  Cls1 cls1;
}



Цитата(Хоббит @  6.1.2009,  15:10 Найти цитируемый пост)
Какой есть выход? Я так понимаю можно сделать поле cls1 типа Cls1*. И в конструкторе создать объект через new, но его тогда надо будет потом удалить... иначе утечка памяти.

деструктор  Cls2 для чего тебе дан?
Код

class Cls2 {
public:
  Cls2(  ) : cls1(0) { int param = 2; cls1 = new Cls1(param )};
  ~Cls2(){delete cls1;}
  Cls1 *cls1;
}

Цитата(Хоббит @  6.1.2009,  15:10 Найти цитируемый пост)
А чтобы его корректно удалить, надо заводить конструктор копий для этого объекта счетчик ссылок. Или использовать безопасные указатели, что тоже не хотелось бы. 

Конструктор копии тут пишется за 1 минуту, а счетчик ссылок нужен только если объект cls1 разделяемый , в чем я сильно сомневаюсь. И даже в этом случае проблемы никакой нет. 


Это сообщение отредактировал(а) Fazil6 - 6.1.2009, 15:39
PM MAIL   Вверх
Хоббит
Дата 6.1.2009, 18:40 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Завсегдатай
Сообщений: 1263
Регистрация: 6.11.2005

Репутация: нет
Всего: 1



Я к тому что если в программе сделать так

Код

Cls2 cls2;

otherMethod(cls2);



То при запуске метода cls2 с копируется, а при завершении метода для копии вызовется деструктор, который очистит память по указателю. После завершения программы для основного объекта опять вызовется деструктор и будет попытка очистить память второй раз.

Про список инициализации сейчас прочитаю.
PM MAIL   Вверх
Fazil6
Дата 6.1.2009, 18:52 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Завсегдатай
Сообщений: 1653
Регистрация: 3.5.2006
Где: Минск

Репутация: 7
Всего: 60



Цитата(Хоббит @  6.1.2009,  18:40 Найти цитируемый пост)
То при запуске метода cls2 с копируется, а при завершении метода для копии вызовется деструктор, который очистит память по указателю. После завершения программы для основного объекта опять вызовется деструктор и будет попытка очистить память второй раз.

ну так на то и пишется коструктор копии, чтобы не указатель копировался, а объект
PM MAIL   Вверх
Хоббит
Дата 6.1.2009, 18:58 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Завсегдатай
Сообщений: 1263
Регистрация: 6.11.2005

Репутация: нет
Всего: 1



Я так понял, список инициализации поможет, если параметры конструктора cls1 определены в прототипе конструктора Cls2, что то вроде

Код

class Cls2 {
public:
  Cls2(int param) : cls1(param) {};
  ...
}


А что делать, если параметр инициализации, определяется только внутри конструктора Cls2. Второй вариант с указателями?

Добавлено через 1 минуту и 9 секунд
Fazil6 ... а если у меня указатель на объект вроде MYSQL_RES, как его скопировать?
PM MAIL   Вверх
mes
Дата 6.1.2009, 19:16 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


любитель
****


Профиль
Группа: Участник Клуба
Сообщений: 7954
Регистрация: 14.1.2006

Репутация: 79
Всего: 250



Цитата(Хоббит @  6.1.2009,  17:58 Найти цитируемый пост)
у меня указатель на объект вроде MYSQL_RES, как его скопировать? 

если храните указатель на некопируемый объект, то 
1. либо объект хозяин Вы должен сделать не копируемым
2. либо реализовать сов;местное пользование этим ресурсом (подсчет ссылок)


Цитата(Хоббит @  6.1.2009,  17:58 Найти цитируемый пост)

А что делать, если параметр инициализации, определяется только внутри конструктора Cls2. Второй вариант с указателями?

приведите пример чего хотите (инициализировать в списке параметров можно к примеру результатом (статической) функции)



--------------------
PM MAIL WWW   Вверх
Хоббит
Дата 6.1.2009, 22:17 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Завсегдатай
Сообщений: 1263
Регистрация: 6.11.2005

Репутация: нет
Всего: 1



Пример
Код

class Cls1 {
public:
  Cls1(int param) {param_ = param};
  ~Cls1() {};  

private:
  param_;
}

class Cls2 {
public:
  Cls2() { вычисляем int variable; инициализируем cls1(variable)};
  ~Cls2();
  Cls1 cls1;
}


PM MAIL   Вверх
mes
Дата 6.1.2009, 22:26 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


любитель
****


Профиль
Группа: Участник Клуба
Сообщений: 7954
Регистрация: 14.1.2006

Репутация: 79
Всего: 250



Цитата(Хоббит @  6.1.2009,  21:17 Найти цитируемый пост)
Пример

так пример нужен не того как написать класс (как я понял в этом то и вопрос),
а вычисления какого типа необходимы. 
Ну вот так можно :
Код

Cls2 {
public:
  Cls2() : cls1 (getint()) { };
  ~Cls2();
   static int getint() { return 5; } 
  Cls1 cls1;
};





--------------------
PM MAIL WWW   Вверх
Хоббит
Дата 7.1.2009, 08:57 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Завсегдатай
Сообщений: 1263
Регистрация: 6.11.2005

Репутация: нет
Всего: 1



Ясно. Мне этого достаточно. Всем спасибо.

Это сообщение отредактировал(а) Хоббит - 7.1.2009, 08:57
PM MAIL   Вверх
Хоббит
Дата 10.1.2009, 10:28 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Завсегдатай
Сообщений: 1263
Регистрация: 6.11.2005

Репутация: нет
Всего: 1



А можно делать вот так?

Код

class Cls2 {
  Cls2(Cls1 cls1) {/*Объект копируется при передаче параметра и мы получаем на него ссылку*/ cls1_ = &cls1;}
  ~Cls2() {/*нужно ли тут в деструкторе удалять указатель cls1_*/};

private:
  Cls1* cls1_;
}

PM MAIL   Вверх
pan2004
Дата 10.1.2009, 10:36 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 357
Регистрация: 28.7.2007

Репутация: 2
Всего: 9



Цитата(Хоббит @  10.1.2009,  10:28 Найти цитируемый пост)
/*Объект копируется при передаче параметра и мы получаем на него ссылку*/

...и потом вылетаем по ошибке защиты памяти на ближайшей строке...
нет, нельзя.
cls1 здесь будет локальной переменной, видимой только в конструкторе(про время жизни стековых переменных слышал?). Соответственно, если ты попытаешься "достучатся" до этой переменной откуда-нибудь еще, она уже прекратит свое существование и ОС прихлопнет программу. Все.


--------------------
Qt4/C++ fan
WinXP SP3: MSVC++2005 Qt4.5.1 Boost1.39
сыграем в дурака?
PM MAIL   Вверх
Хоббит
Дата 10.1.2009, 12:54 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Завсегдатай
Сообщений: 1263
Регистрация: 6.11.2005

Репутация: нет
Всего: 1



Тогда создать ссылку на копию и удалить указатель, когда он не нужен будет?

Код

class Cls2 {
 Cls2(Cls1 cls1) {cls1_ = new Cls1(cls1)};
 ~Cls2() {delete cls1_;};

private:
  Cls1* cls1;
}

PM MAIL   Вверх
mes
Дата 10.1.2009, 13:24 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


любитель
****


Профиль
Группа: Участник Клуба
Сообщений: 7954
Регистрация: 14.1.2006

Репутация: 79
Всего: 250



Цитата(Хоббит @  10.1.2009,  11:54 Найти цитируемый пост)
Тогда создать ссылку на копию и удалить указатель, когда он не нужен будет?

*создать динамический(в куче) объект и присвоить его указателю, и удалить (объект, а не указатель) когда он будет не нужен. smile

Цитата(Хоббит @  10.1.2009,  11:54 Найти цитируемый пост)
{cls1_ = new Cls1(cls1);};

если у Вас определен конструктор копирования, то можно. 
Хотя, показанное в Вашем примере, является излишeством - но предполагаю Вы просто сильно упростили для примера. smile


Это сообщение отредактировал(а) mes - 10.1.2009, 13:27


--------------------
PM MAIL WWW   Вверх
  
Ответ в темуСоздание новой темы Создание опроса
Правила форума "C/C++: Для новичков"
JackYF
bsa

Запрещается!

1. Публиковать ссылки на вскрытые компоненты

2. Обсуждать взлом компонентов и делиться вскрытыми компонентами

  • Действия модераторов можно обсудить здесь
  • С просьбами о написании курсовой, реферата и т.п. обращаться сюда
  • Вопросы по реализации алгоритмов рассматриваются здесь


Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, JackYF, bsa.

 
0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | C/C++: Для новичков | Следующая тема »


 




[ Время генерации скрипта: 0.0613 ]   [ Использовано запросов: 22 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.