потом видимо при переходе на очередную версию gcc это дело перестало работать (?) и оказалось закомментированным.
На место вышеозначенного кода пришло следующее:
class SomeClass
{
...
};
SomeClass x[100];
...
for(..)
{
// g++ does not allow the automatic casting
// x[i] = SomeClass();
SomeClass sc = SomeClass();
x[i] = sc;
}
Правда второй вариант тоже не собирается, поскольку у SomeClass не объявлен копирующий конструктор.
Я вообще не каждый день пишу на С++, поэтому тонкости ускользают и/или забываются.
Объясните-ка мне, что автор вообще хотел сказать конструкцией вида x[i] = SomeClass(); ?
Каков смысл в вызове конструктора напрямую без new?
Другой мой коллега утверждает, что
void proc()
{
SomeClass();
}
не только вызовет конструктор, но и _выделит_ память под безымянный объект в стеке и еще и деструктор вызовется при выходе из процедуры.
Какой толк вызывать вне класса его конструктор напрямую без new и без объявления переменной (кроме исполнения самого кода конструктора)?
R>потом видимо при переходе на очередную версию gcc это дело перестало работать (?) и оказалось закомментированным. R>На место вышеозначенного кода пришло следующее: R>
R>потом видимо при переходе на очередную версию gcc это дело перестало работать (?) и оказалось закомментированным. R>На место вышеозначенного кода пришло следующее: R>
R>Правда второй вариант тоже не собирается, поскольку у SomeClass не объявлен копирующий конструктор.
R>Я вообще не каждый день пишу на С++, поэтому тонкости ускользают и/или забываются. R>Объясните-ка мне, что автор вообще хотел сказать конструкцией вида x[i] = SomeClass(); ?
Он хотел сказать, что не знает С++.
Конструктор там и так вызовется
SomeClass x[100]; // приведет к вызову 100 конструкторов
А тот, кто этот код писал, потом еще раз создавал 100 объектов, и присваивал их значение каждому элементу соответственно.
R>Каков смысл в вызове конструктора напрямую без new?
В С++ нет синтаксической конструкции "вызов конструктора".
R>Другой мой коллега утверждает, что R>
R>void proc()
R>{
R> SomeClass();
R>}
R>
R>не только вызовет конструктор, но и _выделит_ память под безымянный объект в стеке и еще и деструктор вызовется при выходе из процедуры.
Так и есть.
R>Какой толк вызывать вне класса его конструктор напрямую без new и без объявления переменной (кроме исполнения самого кода конструктора)?
не плохо было бы ещё деструкторы повызывать... обьекты там уже созданы...
class SomeClass
{
...
};
SomeClass x[100];
...
// допустим тут решили их пересоздать...for(..)
{
x[i]~SomeClass(); //убить старыйnew (&x[i]) SomeClass(); //создать новый по старому адресу
}
Здравствуйте, Caracrist, Вы писали:
C>Здравствуйте, Caracrist, Вы писали:
C>> C>>
C>SomeClass x[100];
C>...
C>// допустим тут решили их пересоздать...
C>for(..)
C>{
C> x[i]~SomeClass(); //убить старый
C> new (&x[i]) SomeClass(); //создать новый по старому адресу
C>}
C>
Здравствуйте, Rothmans, Вы писали:
R>Каков смысл в вызове конструктора напрямую без new? R>Какой толк вызывать вне класса его конструктор напрямую без new и без объявления переменной (кроме исполнения самого кода конструктора)?
Объекты в C++ могут создавать в динамической памяти (new) либо быть временными значениями (без new, живут на стеке). Объекты в динамической памяти могут жить пока не удалят, они аналогичны объектам в Java. А временные удаляются при выходе из области видимости, и в другое место передаются копированием, они аналогичны значениям в функциональных языках.
struct Sputnik
{
boost::reference_wrapper<int> pogodaSeichas;
Sputnik(int & pogoda) : pogodaSeichas(pogoda){}
void reset(int & pogoda) { pogodaSeichas = boost::reference_wrapper<int>(pogoda); } // это то место, за которые ты так уцепился
};
// наcледование убрал - инкапсуляцию нарушает и запутывает, лучше так:class SomeClass
{
int pogoda[31];
Sputnik sp_;
public:
SomeClass()
: sp_(pogoda[KakoysegodnyaDen()])
{
}
void reset()
{
sp_.reset(pogoda[KakoysegodnyaDen()]);
}
}
Только дело ведь не в том, что тут костыль с инициализацией ссылки, а в том, насколько часто такое встречается. Если ты хотел показать, что такие приемы бывают нужны — поздравляю, тебе это удалось. Но нужно ли так делать всегда — большой вопрос.
, другие подхватили. Не знаю на счет "синтаксической конструкции", но вызов конструктора есть: у любого конструктора есть соглашение о вызове, и этим понятием оперирует стандарт, см., например, п. 3.8/1
--
Справедливость выше закона. А человечность выше справедливости.
Здравствуйте, rg45, Вы писали:
R>Здравствуйте, wander, Вы писали:
R>>>Каков смысл в вызове конструктора напрямую без new? W>>В С++ нет синтаксической конструкции "вызов конструктора".
R>Ну вот, один сказал
, другие подхватили. Не знаю на счет "синтаксической конструкции", но вызов конструктора есть: у любого конструктора есть соглашение о вызове, и этим понятием оперирует стандарт, см., например, п. 3.8/1
Нет. Тут четко был определен смысл фразы. Человек думал, что здесь не создается объекта, а происходит вызов "как бы функции-конструктора". Это я и имел в виду. Насчет чего подхватили — не понял.
Здравствуйте, rg45, Вы писали:
R>Здравствуйте, wander, Вы писали:
R>>>Каков смысл в вызове конструктора напрямую без new? W>>В С++ нет синтаксической конструкции "вызов конструктора".
R>Ну вот, один сказал
, другие подхватили. Не знаю на счет "синтаксической конструкции", но вызов конструктора есть: у любого конструктора есть соглашение о вызове, и этим понятием оперирует стандарт, см., например, п. 3.8/1
Я как-то давно в коде коллеги увидел вот такое:
class SomeClass
{
int a_;
public:
SomeClass()
{
SomeClass(5);
}
SomeClass(int a)
: a_(a)
{
}
};
Здравствуйте, Caracrist, Вы писали:
C>Здравствуйте, wander, Вы писали:
C>Подключил буст, сделал редизайн... Это не плохо и скорее даже к лучшему, но не всегда доступно.
W>> Но нужно ли так делать всегда — большой вопрос.
C>Согласен! C>Скажу даже больше, только когда нет выбора и нет возможности сделать редизайн... (а я понял, что у топикастера именно такая ситуация)
Да не, че там выкину повторную инициализацию членов массива для начала, чтобы компилировалось хотя бы.
Здравствуйте, wander, Вы писали:
R>>>>Каков смысл в вызове конструктора напрямую без new? W>>>В С++ нет синтаксической конструкции "вызов конструктора".
R>>Ну вот, один сказал
, другие подхватили. Не знаю на счет "синтаксической конструкции", но вызов конструктора есть: у любого конструктора есть соглашение о вызове, и этим понятием оперирует стандарт, см., например, п. 3.8/1
W>Нет. Тут четко был определен смысл фразы. Человек думал, что здесь не создается объекта, а происходит вызов "как бы функции-конструктора". Это я и имел в виду. Насчет чего подхватили — не понял.
По сути сказанного тобой я полностью согласен. Что меня удивило, так это точность совпадения твоей фразы с тем, что было совершенно не к месту написано здесь
Здравствуйте, rg45, Вы писали:
R>Здравствуйте, wander, Вы писали:
R>>>>>Каков смысл в вызове конструктора напрямую без new? W>>>>В С++ нет синтаксической конструкции "вызов конструктора".
R>>>Ну вот, один сказал
, другие подхватили. Не знаю на счет "синтаксической конструкции", но вызов конструктора есть: у любого конструктора есть соглашение о вызове, и этим понятием оперирует стандарт, см., например, п. 3.8/1
W>>Нет. Тут четко был определен смысл фразы. Человек думал, что здесь не создается объекта, а происходит вызов "как бы функции-конструктора". Это я и имел в виду. Насчет чего подхватили — не понял.
R>По сути сказанного тобой я полностью согласен. Что меня удивило, так это точность совпадения твоей фразы с тем, что было совершенно не к месту написано здесь
. Фразы совпадают с точностью до символа, поэтому я невольно решил, что тут не обошлось без повторов.
Прочитал ту ветку — забавно. R>Если я ошибся, приношу извинения.
Все нормально!
Здравствуйте, Rothmans, Вы писали:
R>Здравствуйте, Rothmans, Вы писали:
R>>Да не, че там выкину повторную инициализацию членов массива для начала, чтобы компилировалось хотя бы.
R>Так так.. это я погорячился. R>Смысл кода очевидно именно в очистке массива (приведении его в исходный вид). R>
R>потом видимо при переходе на очередную версию gcc это дело перестало работать (?) и оказалось закомментированным.
Версии компиляторов стремятся к несовместимости (по разным причинам).
При переходе все и проявляется..
R>На место вышеозначенного кода пришло следующее: R>
R>Правда второй вариант тоже не собирается, поскольку у SomeClass не объявлен копирующий конструктор.
Зачем копировать?
// или обойтись без копирования,
// дополняя парой функций (де)инициализации класс SomeClass:
// int Init() {/*Do init*/}
// void Exit() {/*Do exit*/} // в деструкторе не забыть вызвать
// тогда
x[i].Init();
R>Я вообще не каждый день пишу на С++, поэтому тонкости ускользают и/или забываются. R>Объясните-ка мне, что автор вообще хотел сказать конструкцией вида x[i] = SomeClass(); ?
R>Каков смысл в вызове конструктора напрямую без new? R>Другой мой коллега утверждает, что R>
R>void proc()
R>{
R> SomeClass();
R>}
R>
R>не только вызовет конструктор, но и _выделит_ память под безымянный объект в стеке и еще и деструктор вызовется при выходе из процедуры.
R>Какой толк вызывать вне класса его конструктор напрямую без new и без объявления переменной (кроме исполнения самого кода конструктора)?
Служебные операции захвата (или прочее) объекта должны быть выполнены при входе и освобождены при выходе. Стековая переменная для этих целей подходит, указатель на динамическую память подходит только в стековой оболочке (врепере). При этом, обращение к переменной, обычно, не нужно.
New — медленная функция, стэк быстрее работает.
R>Спасибо!
Здесь есть одна потенциальная проблема — если в точках 1 и 2 возможна генераци исключений, то реализация функции 'clearX' не удовлетворяет 'strong exception guarantee' т.к. алгоритм ее работы заключается в изменении объектов из некоторого диапазона 'по месту'. Если операция изменения (или любая ее часть) приведет к генерации исключения, то содержимое массива будет представлять собой совокупность 'очищенных' элементов и элементов со старыми значениями (кроме исключения в точке 1 при первой итерации). Полноценный откат к состоянию, в котором находился объект типа 'MyContainer' до вызова 'clearX' при такой реализации невозможен, т.к. некоторые значения будут потеряны.
Проблема решается посредством создания временного объекта-массива, члены которого инициализированы неким образом и выполнении nothrow swap'a с объектом-членом (или явного почленного swap'a для подобъектов массива).