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

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> Вызов одного конструктора из другого, В пределах одного класса 
V
    Опции темы
SaDFromSpb
Дата 1.6.2006, 02:49 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


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

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



Можно ли реализовать вот этот Java-класс на Си++ ?
Код
class SomeClass 
{

   public SomeClass() {
      this(2, 3);
   }

   public SomeClass(int _x, int _y) {
      x = _x; y = _y;
   }

   private int x, y;

}
То есть, можно ли вызвать один конструктор из другого? Это мелочи, конечно. Можно отдельный метод инициализации сделать. Но все-таки интересно.
У меня, как я не пытался, не получилось.  smile  


--------------------
"За исключением части, касающейся потоков, библиотека Loki написана на стандартном языке С++. Увы, это означает, что многие современные компиляторы не смогут работать с ней в полном объеме." (А. Александреску. Modern C++ design. 2001)
PM   Вверх
Daevaorn
Дата 1.6.2006, 06:48 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


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

Репутация: 51
Всего: 70



Код

class SomeClass
{
public:
   SomeClass()
   {
      new(this) SomeClass( 2, 3 );
   }
   SomeClass( intm _x, int _y )
      :x( _x ), y( _y )
   {
   }
private:
   int x;
   int y;
};


Есть подводные камни, но работать должно. Лучше так не далать, это по сути, ошибка проектирования. 
PM MAIL WWW   Вверх
MAKCim
Дата 1.6.2006, 09:16 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Воін дZэна
****


Профиль
Группа: Экс. модератор
Сообщений: 5644
Регистрация: 10.12.2005
Где: Менск, РБ

Репутация: 52
Всего: 207



Цитата

Есть подводные камни, но работать должно. Лучше так не далать, это по сути, ошибка проектирования.  

уж лучше тогда в данном случае
Код

class SomeClass
{
public:
   SomeClass()
   {
      *this=SomeClass(2,3);
   }
   SomeClass( intm _x, int _y )
      :x( _x ), y( _y )
   {
   }
private:
   int x;
   int y;
};

а еще лучше сделать приемлемые параметры по умолчанию 


--------------------
Ах, у елі, ах, у ёлкі, ах, у елі злыя волкі ©

PM MAIL   Вверх
SaDFromSpb
Дата 1.6.2006, 11:04 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


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

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



Да... здесь лучше сделать параметры по умолчанию. (А в яве нет параметров по умолчанию) Пример просто не удачен.
Вот с операцией new(this) мне понравилось. Я видел в бнф, что у new скобки есть, а для чего они нужны не понимал. Значит, при такой форме она новую память не выделяет... 


--------------------
"За исключением части, касающейся потоков, библиотека Loki написана на стандартном языке С++. Увы, это означает, что многие современные компиляторы не смогут работать с ней в полном объеме." (А. Александреску. Modern C++ design. 2001)
PM   Вверх
MAKCim
Дата 1.6.2006, 11:51 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Воін дZэна
****


Профиль
Группа: Экс. модератор
Сообщений: 5644
Регистрация: 10.12.2005
Где: Менск, РБ

Репутация: 52
Всего: 207



Цитата

Значит, при такой форме она новую память не выделяет...  

да, это placement new 


--------------------
Ах, у елі, ах, у ёлкі, ах, у елі злыя волкі ©

PM MAIL   Вверх
DeadSoul
Дата 1.6.2006, 11:53 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


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

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



Цитата(SaDFromSpb @  1.6.2006,  11:04 Найти цитируемый пост)
Вот с операцией new(this) мне понравилось. Я видел в бнф, что у new скобки есть, а для чего они нужны не понимал. Значит, при такой форме она новую память не выделяет...  

Не нужно это в таком месте. В данном месте рулят параметры по умолчанию и единственный конструктор.
Код

SomeClass(int x=2, int y=3);
 


--------------------
 Если Вы получили ответ на Ваш вопрос, то нажмите на "Вопрос решен". 

Бьем спамеров их же оружием. Пусть весь спам сыпется им
[email protected] 
PM   Вверх
maxim1000
Дата 1.6.2006, 12:32 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


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

Репутация: 17
Всего: 110



Цитата(DeadSoul @  1.6.2006,  10:53 Найти цитируемый пост)
Не нужно это в таком месте. В данном месте рулят параметры по умолчанию и единственный конструктор

не факт
если сделать параметрыпо умолчанию, то никто не помешает передать один, а это значит, что нельзя уже сделать консруктор с одним параметром
пример:
когда без параметров - 2,3
когда с одним параметром - эквивалентно x,x 


--------------------
qqq
PM WWW   Вверх
SaDFromSpb
Дата 1.6.2006, 12:42 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


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

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



DeadSoul
Цитата
Не нужно это в таком месте. В данном месте рулят параметры по умолчанию и единственный конструктор.
 Да я и не говорю, что это нужно в этом месте. Довольно ясно, что С++ вообще не рассчитан на вызов одного конструктора из другого. 


--------------------
"За исключением части, касающейся потоков, библиотека Loki написана на стандартном языке С++. Увы, это означает, что многие современные компиляторы не смогут работать с ней в полном объеме." (А. Александреску. Modern C++ design. 2001)
PM   Вверх
Nuzur
Дата 1.6.2006, 17:23 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


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

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



SaDFromSpb, факт. 


--------------------
Never again...
PM MAIL   Вверх
MAKCim
Дата 1.6.2006, 18:03 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Воін дZэна
****


Профиль
Группа: Экс. модератор
Сообщений: 5644
Регистрация: 10.12.2005
Где: Менск, РБ

Репутация: 52
Всего: 207



Цитата

вообще не рассчитан на вызов одного конструктора из другого. 

что по мне вполне логично 


--------------------
Ах, у елі, ах, у ёлкі, ах, у елі злыя волкі ©

PM MAIL   Вверх
akahan
Дата 1.3.2007, 16:00 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



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

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



Подниму опять эту тему, т.к. не совсем понял.
Из вышесказанного получается, что С++ не предусматривает возможность вызова одного конструктора из другого. 
Это действительно так?
И будет ли работать вот этот код? Всмысле какие могут быть последствия этого кода, если могут быть????
Код

class SomeClass
{
public:
   SomeClass()
   {
      *this=SomeClass(2,3);
   }
   SomeClass( intm _x, int _y )
      :x( _x ), y( _y )
   {
   }
private:
   int x;
   int y;
};

PM MAIL   Вверх
maxim1000
Дата 1.3.2007, 16:25 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


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

Репутация: 17
Всего: 110



это приводит к созданию на стеке нового объекта, потом присваиванию его полей текущему (консруктор которого вызывается), а потом - удалению промежуточного
конечно, оптимизатор может сильно сократить этот набор действий (может, даже сделать его эквивалентным вызову конструктора с параметрами), но далеко не в каждом случае
даный случай - довольно-таки простой, так что вроде всё должно быть нормально
но при усложнении структуры объектов, могут начаться неоправданные затраты ресурсов
кроме того, не все классы позволяют присваивание одних объектов другим, так что способ не очень универсальный

есть ещё один вариант: напимать protected/private метод, который будет содержать код второго конструктора, и вызывать его из обоих
он тоже имеет недостаток - некоторые поля (например, const или ссылки) могут не поддерживать присваивания, а списки инициализации доступны только в конструкторе, да и опять же в случае использования такого метода, поля-объекты сначала создадутся, а уже потом им присвоят значения, что тоже может повлечь неоправданные затраты ресурсов...


--------------------
qqq
PM WWW   Вверх
Earnest
Дата 2.3.2007, 17:10 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Экс. модератор
Сообщений: 5962
Регистрация: 17.6.2005
Где: Рязань

Репутация: 53
Всего: 183



Цитата(akahan @  1.3.2007,  17:00 Найти цитируемый пост)
Из вышесказанного получается, что С++ не предусматривает возможность вызова одного конструктора из другого. 
Это действительно так?

Да, так. Вышеприведенные методы в простых случаях работают, но не универсальны и являются ничем не оправданным извращением.
Проблемы начнутся (скорее всего) при наследовании и (точно) если объект не copy-constructable. 

Проблемы с многократным написанием кода инициализациии (от чего призван избавить описанный изврат) решаются изменением дизайна:
1) константы - а так ли уж надо использовать константы внутри классов? Это все решается инкапсуляцией + соотв. функции. Ну если уж очень хочется, руки не отваляться инициализировать ее в каждом конструкторе.
2) ссылки. Опять же, если так влом инициализировать в каждом конструкторе - ну замени на указатель и инициализируй в общей функции.
3) вложенные объекты, которые при конструировании могут сожрать много ресурсов, а потом их нужно переинициализировать ... - тоже переходим на указатели... "лишнюю" инициализацию указателей или простых типов, полагаю, можно простить...

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



--------------------
...
PM   Вверх
Xenon
Дата 2.3.2007, 21:16 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


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

Репутация: 11
Всего: 50



MAKCim, в C# это практикуется с большой силой, что помогает уменьшить объем кода вбиваемо. В принципе , я так глянул - не сильно это читаемость убивает. Но лучше не заигрываться, конечно.


--------------------
user posted image  
PM MAIL   Вверх
SaDFromSpb
Дата 3.3.2007, 02:31 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


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

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



Цитата(Xenon @  2.3.2007,  21:16 Найти цитируемый пост)
в C# это практикуется с большой силой, что помогает уменьшить объем кода вбиваемо.

Нда... В яве к этой фишке тоже быстро привыкаешь....
С одной стороны это может быть и академически неправильно, зато довольно удобно, когда нет такой фишки, как параметры по умолчанию smile.
А вообще в джаге еще много чего нет smile. Ну это уже так.... лирика....


Это сообщение отредактировал(а) SaDFromSpb - 3.3.2007, 02:42


--------------------
"За исключением части, касающейся потоков, библиотека Loki написана на стандартном языке С++. Увы, это означает, что многие современные компиляторы не смогут работать с ней в полном объеме." (А. Александреску. Modern C++ design. 2001)
PM   Вверх
  
Ответ в темуСоздание новой темы Создание опроса
Правила форума "С++:Общие вопросы"
Earnest Daevaorn

Добро пожаловать!

  • Черновик стандарта C++ (за октябрь 2005) можно скачать с этого сайта. Прямая ссылка на файл черновика(4.4мб).
  • Черновик стандарта C (за сентябрь 2005) можно скачать с этого сайта. Прямая ссылка на файл черновика (3.4мб).
  • Прежде чем задать вопрос, прочтите это и/или это!
  • Здесь хранится весь мировой запас ссылок на документы, связанные с C++ :)
  • Не брезгуйте пользоваться тегами [code=cpp][/code].
  • Пожалуйста, не просите написать за вас программы в этом разделе - для этого существует "Центр Помощи".
  • C++ FAQ

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

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


 




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


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

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