Delphi vs C++ vs C#
, ну и Java немножко, где-то ближе к старшему байту номеров страниц
![]() |
Наши проекты:
Журнал · Discuz!ML · Wiki · DRKB · Помощь проекту |
|
| ПРАВИЛА | FAQ | Помощь | Поиск | Участники | Календарь | Избранное | RSS |
| [216.73.216.192] |
|
|
Правила раздела:
| Страницы: (495) « Первая ... 409 410 [411] 412 413 ... 494 495 ( Перейти к последнему сообщению ) |
Delphi vs C++ vs C#
, ну и Java немножко, где-то ближе к старшему байту номеров страниц
|
Сообщ.
#6151
,
|
|
|
|
Какой же тут диссонанс, если какой-то конструктор уже отработал? |
|
Сообщ.
#6152
,
|
|
|
|
Цитата Кстати D_KEY, когнитивный диссонанс это у тебя не вызывает? Цитата Следует заметить, что если в C++03 объект считается до конца созданным когда его конструктор завершает выполнение, то в C++11 после выполнения хотя бы одного делегирующего конструктора остальные конструкторы будут работать уже над полностью сконструированным объектом. Я еще этот момент в стандарте не смотрел. Если будет вызывать деструктор в таком коде: ![]() ![]() class SomeType { int number; public: SomeType(int new_number) : number(new_number) {} SomeType() : SomeType(42) { throw "aaa"; } }; // ... SomeType x; То да, неприятно. Добавлено А вообще интересную тему поднял, спасибо |
|
Сообщ.
#6153
,
|
|
|
|
Цитата D_KEY @ Я еще этот момент в стандарте не смотрел. Если будет вызывать деструктор в таком коде: Цитата D_KEY @ То да, неприятно. Эээээ?... Неприятно будет, если деструктор не вызовется... Мало ли, мы могли и указатель инициализировать. |
|
Сообщ.
#6154
,
|
|
|
|
Цитата D_KEY @ То да, неприятно. И вообще не очень понятно, что "правильно" делать в этом случае... Добавлено Цитата MyNameIsIgor @ Эээээ?... Неприятно будет, если деструктор не вызовется... Мало ли, мы могли и указатель инициализировать. Но теперь деструктор вызывается в том случае, если не весь код создания выполнен ![]() ![]() class SomeType { public: SomeType(/*...*/) : /*...*/ { /*выделяем какие-то ресурсы*/ } SomeType() : SomeType(/*...*/) { /*выделяем еще какие-то ресурсы*/ } ~SomeType() { // тут мы должны как-то учесть, что у нас создано, что нет и т.п. // т.к. этот деструктор может быть вызван в серединке второго конструктора } }; В результате имеем те проблемы, что и в delphi В общем, что-то тут не то... Будет время - посмотрю в стандарте... Добавлено Надо было делать что-нибудь в духе: ![]() ![]() class SomeType { int number; public: SomeType(int new_number) : number(new_number) {} SomeType() = SomeType(42); }; Вот тогда было бы красиво... |
|
Сообщ.
#6155
,
|
|
|
|
Цитата D_KEY @ Но теперь деструктор вызывается в том случае, если не весь код создания выполнен Создание то выполнено, мы "доустанавливаем инварианты" или хз как это правильнее сказать... Цитата D_KEY @ Вот тогда было бы красиво... Да, если исходить из того, что мы всегда делегируем к более "сложному" конструктору и на не понадобится после него что-то ещё сделать... |
|
Сообщ.
#6156
,
|
|
|
|
Цитата MyNameIsIgor @ Да, если исходить из того, что мы всегда делегируем к более "сложному" конструктору и на не понадобится после него что-то ещё сделать... А что мы можем захотеть сделать еще? В общем, мне пока не нравится |
|
Сообщ.
#6157
,
|
|
|
|
Цитата D_KEY @ А что мы можем захотеть сделать еще? Dunno, перенастроить что-нибудь... |
|
Сообщ.
#6158
,
|
|
|
|
Цитата MyNameIsIgor @ Эээээ?... Неприятно будет, если деструктор не вызовется... Мало ли, мы могли и указатель инициализировать. Не, я все-таки за то, чтобы деструктор самого объекта не вызывался. Думаю, что он и не будет - как и в случае обычного исключения в конструкторе - вызовем деструкторы сконструированных полей и базовых классов. Остальное - задача "вызывающего" конструктора. При таком раскладе, меня, в принципе, все устроит. |
|
Сообщ.
#6159
,
|
|
|
|
Цитата D_KEY @ Думаю, что он и не будет - как и в случае обычного исключения в конструкторе - вызовем деструкторы сконструированных полей и базовых классов. Остальное - задача "вызывающего" конструктора. Конструктор, которому мы делегируем, может быть написан с учётом того, что после выхода из него всё "возвращается на круги своя" в деструкторе. Если же деструктор в случае делегирования не вызовется, то и такого расчёта не должно быть, за чем надо очень внимательно следить - даёшь новые интересные вопросы на внимание для соискателей! |
|
Сообщ.
#6160
,
|
|
|
|
Цитата MyNameIsIgor @ Конструктор, которому мы делегируем, может быть написан с учётом того, что после выхода из него всё "возвращается на круги своя" в деструкторе. Деструктор то один... Цитата Если же деструктор в случае делегирования не вызовется, то и такого расчёта не должно быть, за чем надо очень внимательно следить Точно так же, как и в случае обычных конструкторов Но, судя по всему, деструктор все-таки будет вызван, т.к. конструктором, создающим объект является первый вызванный... А если объект создан, то и деструктор должен быть вызван... Добавлено Напридумывали, блин |
|
Сообщ.
#6161
,
|
|
|
|
Цитата 15.2/2 An object of any storage duration whose initialization or destruction is terminated by an exception will have destructors executed for all of its fully constructed subobjects (excluding the variant members of a union-like class), that is, for subobjects for which the principal constructor (12.6.2) has completed execution and the destructor has not yet begun execution. Similarly, if the non-delegating constructor for an object has completed execution and a delegating constructor for that object exits with an exception, the object’s destructor will be invoked. If the object was allocated in a new-expression, the matching deallocation function (3.7.4.2, 5.3.4, 12.5), if any, is called to free the storage occupied by the object. Добавлено Я понял логику. Мы вызвали конструктор(да, пусть и из другого конструктора), он полностью завершил свою работу, следовательно, нужно и уничтожить созданный объект в случае исключения, как делается во всех других случаях. Т.е. delegating constructor'ы это специальный довесок над нормальными конструкторами для различных доп.действий. В общем, все-равно еще один "интересный вопрос для соискателей" Добавлено Так что Нет |
|
Сообщ.
#6162
,
|
|
|
|
Цитата DesweR @ Эт скучно. Вот шаблоны -- весело http://goran-dev.blogspot.com/2011/11/blog-post.html Оказывается "ноль" это ещё не самое интуитивно непонятное у абстрактных методов... ![]() ![]() #include <vector> template<> void std::vector<int>::push_back(const int& val) { std::cout << "realisation for int" << std::endl; } int main() { std::vector<int> v; v.push_back(1); return 0; } |
|
Сообщ.
#6163
,
|
|
|
|
Цитата Повстанець @ Цитата DesweR @ Эт скучно. Вот шаблоны -- весело http://goran-dev.blogspot.com/2011/11/blog-post.html Оказывается "ноль" это ещё не самое интуитивно непонятное у абстрактных методов... ![]() ![]() #include <vector> #include <iostream> template<> void std::vector<int>::push_back(const int& val) { std::cout << "realisation for int" << std::endl; } int main() { std::vector<int> v; v.push_back(1); return 0; } ![]() Аццкая ошибка компиляции =) ![]() ![]() ~/Programming/cpp $ g++ rebel.cpp rebel.cpp:5:48: error: specialization of ‘void std::vector<_Tp, _Alloc>::push_back(const value_type&) [with _Tp = int, _Alloc = std::allocator<int>, std::vector<_Tp, _Alloc>::value_type = int]’ in different namespace [-fpermissive] rebel.cpp:5:6: error: from definition of ‘void std::vector<_Tp, _Alloc>::push_back(const value_type&) [with _Tp = int, _Alloc = std::allocator<int>, std::vector<_Tp, _Alloc>::value_type = int]’ [-fpermissive] ~/Programming/cpp $ g++ -fpermissive rebel.cpp rebel.cpp:5:48: warning: specialization of ‘void std::vector<_Tp, _Alloc>::push_back(const value_type&) [with _Tp = int, _Alloc = std::allocator<int>, std::vector<_Tp, _Alloc>::value_type = int]’ in different namespace [-fpermissive] rebel.cpp:5:6: warning: from definition of ‘void std::vector<_Tp, _Alloc>::push_back(const value_type&) [with _Tp = int, _Alloc = std::allocator<int>, std::vector<_Tp, _Alloc>::value_type = int]’ [-fpermissive] ~/Programming/cpp $ ./a.out realisation for int ~/Programming/cpp $ |
|
Сообщ.
#6164
,
|
|
|
|
Цитата Повстанець @ Угадай, что произойдёт? Имхо, так нельзя делать. |
|
Сообщ.
#6165
,
|
|
|
|
Цитата korvin @ Эт майкрософтовский и гнушный компиляторы по разному трактуют положения о пространстве имён. Для gcc:Аццкая ошибка компиляции =) ![]() ![]() #include <vector> namespace std { template<> void vector<int>::push_back(const int& val) { std::cout << "realisation for int" << std::endl; } } int main() { std::vector<int> v; v.push_back(1); return 0; } Цитата OpenGL @ Почему? Обычное правило перекрытия, на самом деле. Имхо, так нельзя делать. |