Russian Qt Forum

Разное => Говорилка => Тема начата: nsxwrs от Сентябрь 02, 2016, 15:57



Название: Тестовое задание на программиста С++/Qt компания некстерс
Отправлено: nsxwrs от Сентябрь 02, 2016, 15:57
https://ideone.com/Pv89YH

1.Что выведет код. Ответ 4 - преинкремент а, добавить b, на постинкремент пофиг
Код
C++ (Qt)
int a = 1;
int b = 2;
 
cout<<++a+b--<<endl;

2.Найти ошибку компиляции
Код
C++ (Qt)
void f(string & s)
{
cout<<s<<endl;
}
...
f("hello");
 
   
Код
C++ (Qt)
//Решение, но цепляются и просят другие варианты
void f(const string & s)
 
   
 
}
3.Что выведет код. Ответ 2. Дальше спрашивают про отличия std::vector и QVector и вообще чем контейнеры Qt круче контейнеров STL.
Код
C++ (Qt)
vector<int> v;
v.reserve(10);
for(int i=0;i<10;++i)
v[i]=1;
v.push_back(2);
for(auto a:v)
cout<<a<<endl;
}
4. Что в фрагменте кода неправильно
Удаление массива - delete[] a
Считают, что есть ещё ошибки, спрашивают if(a) избыточно или нет, про исключения если new потерпит неудачу, и чему в этом случае будет а равен
Код
C++ (Qt)
char* a=new char[10];
if(a)
{
delete a;
}
}

5.Что выведет код. Ответ СВ, здесь вроде без подвоха
Код
C++ (Qt)
struct A {
virtual void f(){cout<<"A"<<endl;}
};
struct B {
void f(){cout<<"B"<<endl;}
};
struct C:A,B {
void f(){cout<<"C"<<endl;}
};
...
A* a = new C();
B* b = new C();
 
   

 
6. Что выведет код. Ответ АС, т.к. шаблон частично специализирован для класса В

Код
C++ (Qt)
template<class T>
struct A {
virtual void f(){T()();}
};
struct B {
void operator()(){cout<<"B"<<endl;}
};
struct C:B {
void operator()(){cout<<"C"<<endl;}
};
template<>
struct A<B>
{
void f()
{
cout<<"A"<<endl;
}
};
...
A<B>().f();
A<C>().f();
 

7. Что выведет код. Ответ construct copy хер знает почему.
Код
C++ (Qt)
struct A
{
A()
{
cout<<"construct"<<endl;
}
A(const A&)
{
cout<<"copy"<<endl;
}
A& operator=(const A&)
{
cout<<"assign"<<endl;
return *this;
}
};
 
A f()
{
return A();
}
...
A a1 = f();
A a2 = a1;
 

Какие преимущества взаимодействия объектов через сигнал-слот по сравнению с callback функциями (передача указателя на функцию другого объекта)? По-моему никакого, но некоторым удобнее форма записи. Требуют другого объяснения.

Спрашивают про взаимодействие потоков в Qt. Правильный для них ответ - через сигнал-слот, дальше начинают копать на тему почему это так круто.

Почему графический интерфейс всегда однопоточный?

Расскажите про Implicit sharing в Qt.

Зачем указатель d-> во внутренностях Qt ? (ответ для инкапсуляции не засчитывается, правильно - для бинарной совместимости)

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

Уже к вам вопрос, зачем знание внутренней реализации Qt нужно на должность программиста GUI?


Название: Re: Тестовое задание на программиста С++/Qt компания некстерс
Отправлено: Bepec от Сентябрь 02, 2016, 18:30
Нахрен не нужно...

Если задания про наследование, виртуалы ещё нормальны - проверяют знания, остальные шлак.
Вопросы ещё про сигнал-слоты, многопоточность и Implicit sharing тоже нормальны.

Вспомню своё собеседование - пришёл, пара вопросов про конструктор, деструктор, отрисовку. Дали тестовое задание - сделай блокнот красивый. На след день принёс им чудо блокнот на делфях, с кастомными картинками натянутыми на стандартные элементы :D
На вопрос: "Эт же стандартные элементы?"? Последовал ответ - сказали блокнот, вот блокнот. А остальное не обговаривалось :D Взяли, заодно документацией занимался :P


Название: Re: Тестовое задание на программиста С++/Qt компания некстерс
Отправлено: qate от Сентябрь 02, 2016, 21:10
вообще все вопросы по тему - начало C\C++, затем Qt
пятница, им уже наверно не терпелось, а тут очередной пришел )


Название: Re: Тестовое задание на программиста С++/Qt компания некстерс
Отправлено: Igors от Сентябрь 03, 2016, 05:14
Собеседование проводят крайне недружелюбные ребята (технический директор и ещё кто-то), поэтому и выкладываю всю эту херню.
А по мне так нормальная проверка на "ненулевой", а остального тесты все равно не покажут, в работе смотреть надо. 

Уже к вам вопрос, зачем знание внутренней реализации Qt нужно на должность программиста GUI?
Человек понимающий внутренние механизмы напишет гораздо быстрее и лучше. В общем "недружелюбные ребята" правы

Зачем указатель d-> во внутренностях Qt ? (ответ для инкапсуляции не засчитывается, правильно - для бинарной совместимости)
Этого я не знал  :'(


Название: Re: Тестовое задание на программиста С++/Qt компания некстерс
Отправлено: alex312 от Сентябрь 03, 2016, 06:31
вопрос 3 (про вектор) - runtime error  ;D
Рантайм еррор выдала только студия в дебаге.


Название: Re: Тестовое задание на программиста С++/Qt компания некстерс
Отправлено: Racheengel от Сентябрь 03, 2016, 11:22
в 3 однозначно будет крэш.
reserve только выделяет память, но длина вектора то не меняется.

в 7 - это уже как компилятор соптимизирует. но во 2 случае должен вызваться копи-конструктор, имхо.


Название: Re: Тестовое задание на программиста С++/Qt комп
Отправлено: Пантер от Сентябрь 03, 2016, 11:24
В 3 не будет краша. То есть, иногда может быть. Краш будет где-то в другом месте.


Название: Re: Тестовое задание на программиста С++/Qt комп
Отправлено: Igors от Сентябрь 03, 2016, 12:16
В 3 не будет краша. То есть, иногда может быть. Краш будет где-то в другом месте.
В MSVC debug будет, не раз правил
Код:
int * a = &vec[0];  
if (a) {
...
В одних реализациях std индекс < size() проверяется, в других нет. Для MSVC в debug проверяется, в release нет и, помнится, еще можно управлять через макросы 


Название: Re: Тестовое задание на программиста С++/Qt компания некстерс
Отправлено: nsxwrs от Сентябрь 03, 2016, 14:00
А по мне так нормальная проверка на "ненулевой", а остального тесты все равно не покажут, в работе смотреть надо.  
Человек понимающий внутренние механизмы напишет гораздо быстрее и лучше. В общем "недружелюбные ребята" правы
Они что делают GUI, переписывая Qt под себя?
1,3,4,7 вопрос не имеют однозначного ответа. Ребята ссылаются на стандарт.
В дополнительных проверяется знание рекламных заявлений разработчиков Qt. Например, какая революционная технология сигнал-слот, и её надо использовать всегда и везде.


Название: Re: Тестовое задание на программиста С++/Qt компания некстерс
Отправлено: Racheengel от Сентябрь 03, 2016, 14:35
1 - однозначно 4, независимо от компиля.
4 - насчет delete[] тоже однозначно. насчет new - проверять поинтер смысла нет, т.к. все равно капут проге, если нету памяти.
3 - тут отсутствие крэша скорее исключение, тк. все зависит от реализации библиотеки и компилятора (кстати, в студии в дебаге падает 100%).
7 - да, неоднозначно.


Название: Re: Тестовое задание на программиста С++/Qt компания некстерс
Отправлено: ViTech от Сентябрь 03, 2016, 14:43
Какие преимущества взаимодействия объектов через сигнал-слот по сравнению с callback функциями (передача указателя на функцию другого объекта)? По-моему никакого, но некоторым удобнее форма записи. Требуют другого объяснения.

Спрашивают про взаимодействие потоков в Qt. Правильный для них ответ - через сигнал-слот, дальше начинают копать на тему почему это так круто.

Почему графический интерфейс всегда однопоточный?

И какие Ваши ответы на эти вопросы?

Уже к вам вопрос, зачем знание внутренней реализации Qt нужно на должность программиста GUI?

Чтобы "программист GUI" этот самый GUI не развалил :), особенно если там многопоточность присутствует.


Название: Re: Тестовое задание на программиста С++/Qt компания некстерс
Отправлено: xokc от Сентябрь 03, 2016, 16:13
Какие преимущества взаимодействия объектов через сигнал-слот по сравнению с callback функциями (передача указателя на функцию другого объекта)? По-моему никакого, но некоторым удобнее форма записи. Требуют другого объяснения.
Я бы этим вопросом и ограничился. Впрочем и ответом кандидата тоже, в смысле того, что он бы мне не подошёл :)


Название: Re: Тестовое задание на программиста С++/Qt компания некстерс
Отправлено: gil9red от Сентябрь 03, 2016, 17:51
Какие преимущества взаимодействия объектов через сигнал-слот по сравнению с callback функциями (передача указателя на функцию другого объекта)? По-моему никакого, но некоторым удобнее форма записи. Требуют другого объяснения.
Я бы этим вопросом и ограничился. Впрочем и ответом кандидата тоже, в смысле того, что он бы мне не подошёл :)

Объясните тогда, какой ответ вас бы устроил  :)


Название: Re: Тестовое задание на программиста С++/Qt компания некстерс
Отправлено: Racheengel от Сентябрь 03, 2016, 17:53
Цитировать
Уже к вам вопрос, зачем знание внутренней реализации Qt нужно на должность программиста GUI?
Нужно только, если он собирается портировать Qt на другие платформы.
Иначе нахрен не нужно :)

Цитировать
Какие преимущества взаимодействия объектов через сигнал-слот по сравнению с callback функциями (передача указателя на функцию другого объекта)? По-моему никакого, но некоторым удобнее форма записи. Требуют другого объяснения.
По сути метасистема сигнал-слотов и есть унифицированные коллбэки, но вынесенные за пределы классов, что позволяет программистам абстагироваться от необходимости строить собственную систему коллбэков во первых, а во-вторых, представляет более гибкий менеджмент связей.


Название: Re: Тестовое задание на программиста С++/Qt компания некстерс
Отправлено: nsxwrs от Сентябрь 03, 2016, 19:54
Цитировать
Уже к вам вопрос, зачем знание внутренней реализации Qt нужно на должность программиста GUI?
Нужно только, если он собирается портировать Qt на другие платформы.
Иначе нахрен не нужно :)

Цитировать
Какие преимущества взаимодействия объектов через сигнал-слот по сравнению с callback функциями (передача указателя на функцию другого объекта)? По-моему никакого, но некоторым удобнее форма записи. Требуют другого объяснения.
По сути метасистема сигнал-слотов и есть унифицированные коллбэки, но вынесенные за пределы классов, что позволяет программистам абстагироваться от необходимости строить собственную систему коллбэков во первых, а во-вторых, представляет более гибкий менеджмент связей.

Ничего за пределы классов не вынесено. Ты же сигнал в хидере прописываешь. Расскажете им про менеджмент связей, допилите чатик https://titanium.im/ru/. У них офис больше на спортзал похож. Наверное чтобы легко уволить кого надо за то, что не кодил на работе.


Название: Re: Тестовое задание на программиста С++/Qt компания некстерс
Отправлено: nsxwrs от Сентябрь 03, 2016, 19:58
Чтобы "программист GUI" этот самый GUI не развалил :), особенно если там многопоточность присутствует.
При том, что они сами сказали что GUI всегда однопоточный и спросили почему.


Название: Re: Тестовое задание на программиста С++/Qt компания некстерс
Отправлено: xokc от Сентябрь 03, 2016, 20:39
Какие преимущества взаимодействия объектов через сигнал-слот по сравнению с callback функциями (передача указателя на функцию другого объекта)? По-моему никакого, но некоторым удобнее форма записи. Требуют другого объяснения.
Я бы этим вопросом и ограничился. Впрочем и ответом кандидата тоже, в смысле того, что он бы мне не подошёл :)

Объясните тогда, какой ответ вас бы устроил  :)


Устроил бы ответ в стиле "между этими понятиями вообще мало общего" и последующее обсуждение про циклы обработки событий, взаимодействие потоков и однопоточность GUI. А ответ в стиле того, какой дал кандидат свидетельствует о том, что он вообще не понимает смысла системы сигнал/слот. Такой бы для решения МОИХ задач бы не подошёл.


Название: Re: Тестовое задание на программиста С++/Qt компания некстерс
Отправлено: nsxwrs от Сентябрь 03, 2016, 21:24
А ответ в стиле того, какой дал кандидат свидетельствует о том, что он вообще не понимает смысла системы сигнал/слот. Такой бы для решения МОИХ задач бы не подошёл.

Бесполезно спорить с религиознымии фанатами. В каком священном писании описан этот смысл?


Название: Re: Тестовое задание на программиста С++/Qt компания некстерс
Отправлено: xokc от Сентябрь 03, 2016, 21:33
В каком священном писании описан этот смысл?
Ни в каком. Я нуждаюсь в коллегах, не пересказывающих "писания", а способных самостоятельно разбираться в основных концепциях используемых в команде инструментов. И в этом я с теми людьми, который проводили это собеседование, вполне солидарен.

Бесполезно спорить с религиознымии фанатами.
Тут, безусловно, соглашусь. Потому дальше продолжать общение в выбранном Вами тоне не буду, тем более, что смысла мы оба в этом не видим.


Название: Re: Тестовое задание на программиста С++/Qt компания некстерс
Отправлено: ViTech от Сентябрь 03, 2016, 21:41
При том, что они сами сказали что GUI всегда однопоточный и спросили почему.

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


Название: Re: Тестовое задание на программиста С++/Qt компания некстерс
Отправлено: qate от Сентябрь 03, 2016, 22:06
а почему 7 неоднозначно ?
ведь https://ru.wikipedia.org/wiki/%D0%9E%D0%BF%D0%B5%D1%80%D0%B0%D1%86%D0%B8%D1%8F_%D0%BF%D1%80%D0%B8%D1%81%D0%B2%D0%B0%D0%B8%D0%B2%D0%B0%D0%BD%D0%B8%D1%8F_%D0%B2_%D0%A1%2B%2B


Название: Re: Тестовое задание на программиста С++/Qt компания некстерс
Отправлено: Racheengel от Сентябрь 03, 2016, 22:23
Ты же сигнал в хидере прописываешь.

И что? Сигнал в хедере - это макрос для moc, который пробегает по хедерам и строит эти самые связи "коллбэков". А так бы тебе приходилось в каждом классе заводить мембер типа ISomeCallback *myCallbackPtr, инициализировать его, проверять на нуль, корректно обрабатывать ситуации, когда связанные объекты померли и т.д. Qt-шная метасистема избавляет от этого геморроя :)


Название: Re: Тестовое задание на программиста С++/Qt компания некстерс
Отправлено: nsxwrs от Сентябрь 03, 2016, 22:54
При том, что они сами сказали что GUI всегда однопоточный и спросили почему.

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

У меня требовали объяснения почему взаимодействие потоков должно быть исключительно через сигнал-слот.
Вы с этим согласны и почему?


Название: Re: Тестовое задание на программиста С++/Qt компания некстерс
Отправлено: nsxwrs от Сентябрь 03, 2016, 22:55
а почему 7 неоднозначно ?
ведь https://ru.wikipedia.org/wiki/%D0%9E%D0%BF%D0%B5%D1%80%D0%B0%D1%86%D0%B8%D1%8F_%D0%BF%D1%80%D0%B8%D1%81%D0%B2%D0%B0%D0%B8%D0%B2%D0%B0%D0%BD%D0%B8%D1%8F_%D0%B2_%D0%A1%2B%2B
В википедии и не то напишут. Вот такие люди, начитавшиеся википедии, считают себя самыми умными.


Название: Re: Тестовое задание на программиста С++/Qt компания некстерс
Отправлено: nsxwrs от Сентябрь 03, 2016, 23:00
Qt-шная метасистема избавляет от этого геморроя :)
Система сигнал-слот создаёт дополнительное удобство. Программист в результате пишет немного больше строк полезного кода в единицу времени. Я в этом духе и сказал им, но требуют другого ответа.


Название: Re: Тестовое задание на программиста С++/Qt компания некстерс
Отправлено: ViTech от Сентябрь 04, 2016, 01:43
У меня требовали объяснения почему взаимодействие потоков должно быть исключительно через сигнал-слот.
Вы с этим согласны и почему?

Какие альтернативные варианты межпоточного взаимодействия для объектов Qt? Их плюсы и минусы относительно сигнал-слот? Насколько удобно их использовать в Qt GUI?


Название: Re: Тестовое задание на программиста С++/Qt компания некстерс
Отправлено: Racheengel от Сентябрь 04, 2016, 02:04
У меня требовали объяснения почему взаимодействие потоков должно быть исключительно через сигнал-слот.
Вы с этим согласны и почему?

"Исключительно" через сигнал-слот - это глупость.
Это лишь один из возможных вариантов.
Один поток, например, может иметь очередь объектов, а второй будет ее последовательно вычитывать.
Тут сигнал-слот особо не поможет. Особенно если потоки должны работать асинхронно.


Название: Re: Тестовое задание на программиста С++/Qt компания некстерс
Отправлено: Igors от Сентябрь 04, 2016, 09:19
У меня требовали объяснения почему взаимодействие потоков должно быть исключительно через сигнал-слот.
Вы с этим согласны и почему?
Ну "исключительно" - это уж слишком. Но да, сигнал/слот предоставляет легкий и удобный способ взаимодействия потоков. Вот недавно мелькала такая задача

Нитка 1 получила (или создала) картинку (QImage) и должна передать ее в UI для отрисовки. С помощью слот/сигнал это делается одним движением, напр
Код
C++ (Qt)
signals:
void SendImage( QImage image );
Попробуйте достичь того же без сигнал/слот. Это возможно, но отнюдь не просто


Название: Re: Тестовое задание на программиста С++/Qt компания некстерс
Отправлено: Bepec от Сентябрь 04, 2016, 09:55
Сигнал слоты упрощают работу между потоками, классами, раз эдак в 10. При этом Qt не исключает и старые способы взаимодействия. Так что очень легко можно соединить оба подхода.


Название: Re: Тестовое задание на программиста С++/Qt компания некстерс
Отправлено: Igors от Сентябрь 04, 2016, 10:17
При том, что они сами сказали что GUI всегда однопоточный и спросили почему.
Это "всем известно" но никто не знает "почему". Во всяком случае неубогое Вындоуз может создавать окна в др потоке.


Название: Re: Тестовое задание на программиста С++/Qt компания некстерс
Отправлено: qate от Сентябрь 04, 2016, 16:17
а почему 7 неоднозначно ?
ведь https://ru.wikipedia.org/wiki/%D0%9E%D0%BF%D0%B5%D1%80%D0%B0%D1%86%D0%B8%D1%8F_%D0%BF%D1%80%D0%B8%D1%81%D0%B2%D0%B0%D0%B8%D0%B2%D0%B0%D0%BD%D0%B8%D1%8F_%D0%B2_%D0%A1%2B%2B
В википедии и не то напишут. Вот такие люди, начитавшиеся википедии, считают себя самыми умными.

конкретнее - что там написано не так ?


Название: Re: Тестовое задание на программиста С++/Qt компания некстерс
Отправлено: qate от Сентябрь 04, 2016, 16:20
При том, что они сами сказали что GUI всегда однопоточный и спросили почему.
Это "всем известно" но никто не знает "почему". Во всяком случае неубогое Вындоуз может создавать окна в др потоке.

наверно потому что классы, работающие с gui не потокобезопасны (что может следовать также из принципов работы с графикой)


Название: Re: Тестовое задание на программиста С++/Qt компания некстерс
Отправлено: Igors от Сентябрь 04, 2016, 17:07
наверно потому что классы, работающие с gui не потокобезопасны
Хммм.. а как же рисование в QImage/QPiхmap? Оно ведь вроде безопасно?

(что может следовать также из принципов работы с графикой)
А шо там за прынцыпы такие? Расскажите, мне об этом ничего не известно


Название: Re: Тестовое задание на программиста С++/Qt компания некстерс
Отправлено: gil9red от Сентябрь 04, 2016, 17:50
Чтобы "программист GUI" этот самый GUI не развалил :), особенно если там многопоточность присутствует.
При том, что они сами сказали что GUI всегда однопоточный и спросили почему.

Где-то уже видел ответ на этот вопрос :)
Насколько я помню, ответ был в том, что с гуем работает человек и так получилось, что за окном приложения может за раз работать только один и выполняться только одно определенное действие: клик мыши, нажатие кнопки и т.п. Поэтому нет смысла создавать многопоточное гуи.
И такая концепция не мешает тому, что у приложения может быть несколько потоков: главное с гуи, остальные что-то делают и посылают уведомления гуи.


Название: Re: Тестовое задание на программиста С++/Qt компания некстерс
Отправлено: qate от Сентябрь 04, 2016, 22:54
наверно потому что классы, работающие с gui не потокобезопасны
Хммм.. а как же рисование в QImage/QPiхmap? Оно ведь вроде безопасно?

QWidget and all its subclasses, are not reentrant
http://doc.qt.io/archives/qt-5.5/threads-qobject.html

(что может следовать также из принципов работы с графикой)
А шо там за прынцыпы такие? Расскажите, мне об этом ничего не известно

предполагаю организацию работы через хэндлы, работа с которыми из разных потоков не предусмотрена


Название: Re: Тестовое задание на программиста С++/Qt компания некстерс
Отправлено: ssoft от Сентябрь 05, 2016, 08:55
При том, что они сами сказали что GUI всегда однопоточный и спросили почему.

Это "всем известно" но никто не знает "почему". Во всяком случае неубогое Вындоуз может создавать окна в др потоке.

наверно потому что классы, работающие с gui не потокобезопасны (что может следовать также из принципов работы с графикой)


Ничего сложного в реализации потокобезопасных классов для GUI нет, изначальная проблема совершенно в другом - в выбранной исходной архитектуре и стратегии обработки GUI событий.
Весь набор GUI в Qt представляет собой связанное дерево элементов, для которого необходимо обеспечить "правильный" порядок обработки GUI событий. То есть, например, прежде чем обработать событие HoverEnter для определенного элемента, для всех предыдущих элементов иерархии должны быть обработаны HoverEnter/HoverMove/HoverLeave. Так же предполагается доступ к родительскому и дочерним элементам во время обработки событий. При асинхронной обработке событий невозможно без сложных правил синхронизации (простые мютексы не гарантируют порядок обработки) обеспечить описанное выше поведение. Отсюда появляется архитектурное ограничение - обработка событий в одном потоке. При этом поток не обязан совсем быть главным! Он определяется лишь местом создания обработчика GUI событий. Например, код ниже работает без всяких проблем.

Код
C++ (Qt)
class Thread : public QThread
{
private:
int m_argc;
char ** m_argv;
 
public:
Thread ( int argc, char ** argv )
: m_argc( argc )
, m_argv( argv )
{
}
 
protected:
virtual void run ()
{
QApplication app( m_argc, m_argv );
QWidget widget;
widget.show();
app.exec();
}
};
 
// Начало приложения
int main ( int narg, char ** varg )
{
Thread thread( narg, varg );
thread.start();
thread.wait();
return 0;
}
 

Необходимо отметить, что сам процесс отображения, например, с помощью OpenGL вполне может быть вынесен в отдельный поток или даже в пул потоков.


Название: Re: Тестовое задание на программиста С++/Qt компания некстерс
Отправлено: Igors от Сентябрь 05, 2016, 08:57
Где-то уже видел ответ на этот вопрос :)
Насколько я помню, ответ был в том, что с гуем работает человек и так получилось, что за окном приложения может за раз работать только один и выполняться только одно определенное действие: клик мыши, нажатие кнопки и т.п. Поэтому нет смысла создавать многопоточное гуи.
Слабоватая аргументация. Почему поток не может иметь свое окно(а) GUI которое он сам же и обновляет? Это вполне разумно

QWidget and all its subclasses, are not reentrant
http://doc.qt.io/archives/qt-5.5/threads-qobject.html
И что с того? Да, если я буду дергать setText из разных ниток - наверное рухнет. Ну так синхронизация всегда моя забота если ниток > 1

Может потому что событие рисования посылает ОС и обработчик этого события существует только в главной нитке? (ну это я так думаю, "правельный ответ" не знаю  :))


Название: Re: Тестовое задание на программиста С++/Qt компания некстерс
Отправлено: Igors от Сентябрь 05, 2016, 09:03
Отсюда появляется архитектурное ограничение - обработка событий в одном потоке. При этом поток не обязан совсем быть главным! Он определяется лишь местом создания обработчика GUI событий. Например, код ниже работает без всяких проблем.
Недавно изучал это место. Да, создать UI в "не главной" нитке можно, но будет использоваться другой EventDispatcher. c существенными отличиями.

Необходимо отметить, что сам процесс отображения, например, с помощью OpenGL вполне может быть вынесен в отдельный поток или даже в пул потоков.
С OpenGL можно рисовать синхронно, не дожидаясь события ОС. И что, даже из др нитки работает? (не проверял). Если так - то вот и решение, создал QOpenGLWindow и рисую себе из др нитки. Или это утопия?  :)


Название: Re: Тестовое задание на программиста С++/Qt компания некстерс
Отправлено: ssoft от Сентябрь 05, 2016, 09:19
Если так - то вот и решение, создал QOpenGLWindow и рисую себе из др нитки. Или это утопия?  :)

Так очень часто и делают).


Название: Re: Тестовое задание на программиста С++/Qt компания некстерс
Отправлено: Bepec от Сентябрь 05, 2016, 09:48
Да ответ, я думаю, ещё проще.
Когда разрабатывалось первое UI, никто и не думал, что будет необходимость в многопоточном ui. Да и ресурсы ОС выделялись более бережно.
А так как менять эту систему - значит переписать очень много много кода и ещё больше сил потратить на поддержку устаревших программ, то это никому не надо. Так и живём :D


Название: Re: Тестовое задание на программиста С++/Qt компания некстерс
Отправлено: Old от Сентябрь 05, 2016, 10:04
наверно потому что классы, работающие с gui не потокобезопасны (что может следовать также из принципов работы с графикой)
Да все проще.
Если отвлечься от окон верхнего уровня, которые и так рисуются параллельно разными процессами (правда в буфер), и вспомнить про дочерние виджеты, которые как правило рисует сам процесс (использую GUI-библиотеку). Попробуйте обновлять дочерние виджеты параллельно, особенно если они перекрывают друг-друга. Для правильного отображения все равно придется кому-то одному прорисовывать виджеты в правильном порядке, для организации правильного перекрывания. А сами виджеты легко могут обновлять параллельно в разных потоках, главное что-бы окончательная отрисовка их выполнялась кем-то одним, кто знает в каком порядке их рисовать.


Название: Re: Тестовое задание на программиста С++/Qt компания некстерс
Отправлено: Igors от Сентябрь 05, 2016, 10:05
Так очень часто и делают).
Никогда об этом не слышал, всегда железное "только в главной!!!" :) При случае попробую (ох сомневаюсь все-таки)


Название: Re: Тестовое задание на программиста С++/Qt компания некстерс
Отправлено: Old от Сентябрь 05, 2016, 10:11
Никогда об этом не слышал, всегда железное "только в главной!!!" :) При случае попробую (ох сомневаюсь все-таки)
http://www.gamedev.ru/community/ogl/articles/multithreading


Название: Re: Тестовое задание на программиста С++/Qt компания некстерс
Отправлено: ssoft от Сентябрь 05, 2016, 10:56
Да все проще.
Если отвлечься от окон верхнего уровня, которые и так рисуются параллельно разными процессами (правда в буфер), и вспомнить про дочерние виджеты, которые как правило рисует сам процесс (использую GUI-библиотеку). Попробуйте обновлять дочерние виджеты параллельно, особенно если они перекрывают друг-друга. Для правильного отображения все равно придется кому-то одному прорисовывать виджеты в правильном порядке, для организации правильного перекрывания. А сами виджеты легко могут обновлять параллельно в разных потоках, главное что-бы окончательная отрисовка их выполнялась кем-то одним, кто знает в каком порядке их рисовать.

В том то и дело, что подготовку данных для финального отображения (где учитывается и порядок, и много чего еще - эффекты, текстуры и т.п.) можно совершенно параллельно, да и обрабатывать события GUI и др. можно независимо от финальной процедуры отображения. :) И формально только реализованная в Qt стратегия обработки событий накладывает ограничения на принадлежность всего дерева Widget одному и тому же потоку.


Название: Re: Тестовое задание на программиста С++/Qt компания некстерс
Отправлено: Old от Сентябрь 05, 2016, 11:02
И формально только реализованная в Qt стратегия обработки событий накладывает ограничения на принадлежность всего дерева Widget одному и тому же потоку.
Да ничего она не накладывает. Можно рисовать хоть все виджеты сцены, каждый в своем потоке, правда рисовать придется в буфер (QImage). А вот окончательное рисование придется выполнять в paintEvent. Вот как раз метод paintEvent и вызывает тот самый, кто-знает порядок отрасивки всех виджетов и без кторого нормально сцену не построить.


Название: Re: Тестовое задание на программиста С++/Qt компания некстерс
Отправлено: Igors от Сентябрь 05, 2016, 11:45
В том то и дело, что подготовку данных для финального отображения (где учитывается и порядок, и много чего еще - эффекты, текстуры и т.п.) можно совершенно параллельно, да и обрабатывать события GUI и др. можно независимо от финальной процедуры отображения. :) И формально только реализованная в Qt стратегия обработки событий накладывает ограничения на принадлежность всего дерева Widget одному и тому же потоку.
Думаю "собственно рисованием" занимается обработчик события UpdateRequest. Это он вызывает paintEvent рекурсивно. Начиная с пятерки рисуется все в QImage (хотя это противоречит double-buffer). В конце обработчик вызывает нативный API для вывода на экран.

ОС посылает событие рисования (что выливается в UpdateRequest) в той нитке где создано QApplication (обычно главной). Просто вызвать UpdateRequest из др нитки может и можно (не проверял), но эффекта не имеет т.к. нет dirtyRegions - нужен сначала update, а он вызовет рисование в главной.


Название: Re: Тестовое задание на программиста С++/Qt компания некстерс
Отправлено: GreatSnake от Сентябрь 05, 2016, 12:40
Помимо рисования есть ещё так называемый "focus-manager", который занимается рассылкой клавиатурных событий непосредственно виджетам.
Если кто не знает, то все клавиатурные события от системы приходят в top-level окно и уже непосредственно тулкит занимается их управлением.
Так вот всё это управление тоже далается в обработчике событий gui-потока.


Название: Re: Тестовое задание на программиста С++/Qt компания некстерс
Отправлено: ssoft от Сентябрь 05, 2016, 13:20
Да ничего она не накладывает. Можно рисовать хоть все виджеты сцены, каждый в своем потоке, правда рисовать придется в буфер (QImage). А вот окончательное рисование придется выполнять в paintEvent. Вот как раз метод paintEvent и вызывает тот самый, кто-знает порядок отрасивки всех виджетов и без кторого нормально сцену не построить.

Это только один из возможных методов), нативно реализованный в Qt. Но внутри paintEvent можно только готовить данные для отрисовки кадра (менять атрибуты графических узлов сцены, готовить QImage, или вообще напрямую заполнять массивы в видеопамяти), а непосредственно отображением может заниматься отдельная сущность в отдельном потоке, совершенно никак не связанная ни с QWidget, ни с Qt. Порядок отрисовки зависит только от порядка графических узлов сцены, а частота кадров может никак и не зависеть от частоты вызовов paintEvent.

Вопрос был другой - Почему GUI в Qt всегда однопоточный. Сам процесс отображения не накладывает никаких ограничений на многопоточность GUI, а вот обеспечение правильного порядка обработки событий клавиатуры или мыши можно легко достигнуть с помощью ограничения однопоточности, да и за голыми указателями не нужно следить, и signal/slot в виде Direct соединений, и множество других небрежных плюшек. Изначально GUI было спроектировано таким образом, а далее ...

Цитировать
А так как менять эту систему - значит переписать очень много много кода и ещё больше сил потратить на поддержку устаревших программ, то это никому не надо. Так и живём  :D

Это ограничение так сильно пронизывает Qt, что устранять его не целесообразно. Проще написать другой инструментарий.


Название: Re: Тестовое задание на программиста С++/Qt компания некстерс
Отправлено: Racheengel от Сентябрь 05, 2016, 14:19
Я другого не понимаю - а зачем вам всем так многопоточный гуй сдался? :)
Разве что для второго монитора?
Рисовать в буфер и сейчас можно и в потоках, а потом в главном гуе собирать картинку.
Какие будут преимущества иметь много гуепотоков ???


Название: Re: Тестовое задание на программиста С++/Qt компания некстерс
Отправлено: Old от Сентябрь 05, 2016, 14:24
а непосредственно отображением может заниматься отдельная сущность в отдельном потоке
Ну Тролли и поместили эту сущность в первую (главную) нитку процесса, а могли бы это же делать и в отдельной нитке. Именно эта сущность вызывает paintEvent, а готовить данные для отображения можно в других 100500 нитках.

совершенно никак не связанная ни с QWidget, ни с Qt.
И что получиться: венда/XWindow/...?
Большим достоинством Qt является то, что она может самостоятельно все отрисовать внутри некой области/top-level окна.


Название: Re: Тестовое задание на программиста С++/Qt компания некстерс
Отправлено: Old от Сентябрь 05, 2016, 14:26
Я другого не понимаю - а зачем вам всем так многопоточный гуй сдался? :)
Я бы вообще с удовольствием послушал четкую формулировку "многопоточного гуя". :)


Название: Re: Тестовое задание на программиста С++/Qt компания некстерс
Отправлено: Igors от Сентябрь 05, 2016, 14:37
Я другого не понимаю - а зачем вам всем так многопоточный гуй сдался? :)
Да, применение ограничено, но есть. Не всегда удается вынести трудоемкую операцию в поток чтобы оставить UI свободным. В этом случае хорошо бы рисовать индикатор из "не UI" нитки. В этом году обсуждали.


Название: Re: Тестовое задание на программиста С++/Qt компания некстерс
Отправлено: ssoft от Сентябрь 05, 2016, 15:30
Ну Тролли и поместили эту сущность в первую (главную) нитку процесса, а могли бы это же делать и в отдельной нитке. Именно эта сущность вызывает paintEvent, а готовить данные для отображения можно в других 100500 нитках.

Не могли Троли вызывать paintEvent "и в отдельной нитке" :), так как это привело бы к необходимости синхронизации внутренностей QWidget и производных классов. В этом и отличие отдельной независимой сущности отображения и сущности вызывающей paintEvent.

Цитировать
Я бы вообще с удовольствием послушал четкую формулировку "многопоточного гуя". :)

Здесь как раз все просто). GUI является частным случаем отображением чего-либо. Отображение может складываться из данных разной природы - разные источники данных, разные виды отображаемой информации и т.д. Иногда, целесообразно для данных разной природы иметь независимые друг от друга сущности, управляющие их отображением и реагирующие на события изменения данных (подгрузка, пересчет, уточнение деталлизации данных) или GUI события. Когда отображаемых элементов боольшое количество, а требуемое время отклика достаточно мало, многопоточность становится весьма актуальной.


Название: Re: Тестовое задание на программиста С++/Qt компания некстерс
Отправлено: ssoft от Сентябрь 05, 2016, 15:53
Такой пример. Предположим необходимо отобразить два независимых GUI для управления устройством 1 и устройством 2 в одном. Существует также требование, что изменение состояние устройств должно быть отображено не позднее, чем 100 мс. При выполнении операции после нажатия на кнопку устройства 1 происходит подготовка данных порядка нескольких секунд. Что делать в однопоточной реализации GUI?

Естественное решение - формировать дополнительный поток (с соответствующими накладными расходами), обеспечивающий подготовку данных, или как-то использовать processEvents(). В многопоточном GUI в этом нет необходимости, так как отображение и реакция на события уже многопоточны (асинхронны).


Название: Re: Тестовое задание на программиста С++/Qt компания некстерс
Отправлено: Old от Сентябрь 05, 2016, 16:08
Не могли Троли вызывать paintEvent "и в отдельной нитке" :), так как это привело бы к необходимости синхронизации внутренностей QWidget и производных классов.
Могли. Нужно было синхронизировать только доступ к теневому буферу виджета.

В этом и отличие отдельной независимой сущности отображения и сущности вызывающей paintEvent.
Нет никаких отличий. paintEvent это синоним получения теневого буфера окна. Он необходим для любого варианта отображения.

Здесь как раз все просто). GUI является частным случаем отображением чего-либо. Отображение может складываться из данных разной природы - разные источники данных, разные виды отображаемой информации и т.д. Иногда, целесообразно для данных разной природы иметь независимые друг от друга сущности, управляющие их отображением и реагирующие на события изменения данных (подгрузка, пересчет, уточнение деталлизации данных) или GUI события. Когда отображаемых элементов боольшое количество, а требуемое время отклика достаточно мало, многопоточность становится весьма актуальной.
Можно готовить теневые буферы хоть в 100500 потоках, конечное отображение всегда будет однопоточным. Не могут окна конкурировать друг с другом, каша будет получаться.


Название: Re: Тестовое задание на программиста С++/Qt компания некстерс
Отправлено: Old от Сентябрь 05, 2016, 16:14
Естественное решение - формировать дополнительный поток (с соответствующими накладными расходами), обеспечивающий подготовку данных, или как-то использовать processEvents(). В многопоточном GUI в этом нет необходимости, так как отображение и реакция на события уже многопоточны (асинхронны).
Окна устройства 1 и устройства 2 могут перекрываться, как они будут обновляться на экране?
Окно устройства 1 обновляется 1 раз в 100 мс, окно устройства 2 обновляется 1 раз в 5 сек. Окно устройства 2 перекрывает на половину окно устройства 1. Как будет обновляться видимая часть окна устройства 1? Кто будет это контролировать?


Название: Re: Тестовое задание на программиста С++/Qt комп
Отправлено: ssoft от Сентябрь 05, 2016, 16:54
Окна устройства 1 и устройства 2 могут перекрываться, как они будут обновляться на экране?
Окно устройства 1 обновляется 1 раз в 100 мс, окно устройства 2 обновляется 1 раз в 5 сек. Окно устройства 2 перекрывает на половину окно устройства 1. Как будет обновляться видимая часть окна устройства 1? Кто будет это контролировать?

Да, вполне могут и перекрываться). Кадр или его часть, формируется отдельной сущностью (Renderer), которая оперирует графом графических примитивов. GUI устройств асинхронно оперируют с узлами данного графа, добавляя/изменяя/удаляя их. Renderer в соответствии с этим графом может обновлять кадр по таймеру, или по изменению графа или еще как-то, асинхронно относительно GUI. Порядок рисования кадра определяется графом примитивов, а не каждым GUI устройств отдельно. При этом подготовка кадра Renderer'ом может быть многопроходной и многопоточной (конкурентной) при необходимости.

Асинхронный (многопоточный) GUI не означает независимую друг от друга и конкурирующую отрисовку, а означает независимую обработку событий и управление отображаемыми примитивами. Когда операции одного GUI не блокируют любой другой.


Название: Re: Тестовое задание на программиста С++/Qt комп
Отправлено: Old от Сентябрь 05, 2016, 17:14
Кадр или его часть, формируется отдельной сущностью (Renderer)
Так вот этот самый рендерер и есть та самая сущность, которая однопоточно все отрисовывает. Про нее я вам и речь веду.
Если вы все отрисовки виджетов будете делать в других потоках на QImage, а в paintEvent просто рисовать полученный QImage на виджет, у вас получиться тот самый способ отрисовки, в котором Qt будет в роли рендерера.


Название: Re: Тестовое задание на программиста С++/Qt компания некстерс
Отправлено: ssoft от Сентябрь 05, 2016, 17:43
Так вот этот самый рендерер и есть та самая сущность, которая однопоточно все отрисовывает. Про нее я вам и речь веду.

Так это я давно понял  ;D. Просто многопоточный GUI (о чем собственно разговор) и способ отображения - разные вещи. Многопоточный GUI подразумевает независимую реакцию элементов GUI на события, без явных взаимных блокировок друг друга и рендерера. А уж каким способом происходит формирование кадра (граф, набор QImage или др.) это уже дело конкретной реализации рендерера. При этом рендерер сам по себе может быть и многопоточный, те же QImage можно совмещать и параллельно для разных ветвей иерархии.

PS: Да, и нарямую вызывать метод paintEvent чревато, так как GUI элемент может быть и удален ненароком в момент вызова, отображаем то асинхронно. Лучше уж QImage держать независимо от GUI в отдельном дереве рендерера.


Название: Re: Тестовое задание на программиста С++/Qt компания некстерс
Отправлено: Old от Сентябрь 05, 2016, 20:04
При этом рендерер сам по себе может быть и многопоточный, те же QImage можно совмещать и параллельно для разных ветвей иерархии.
Нет. Если элементы ветвей могут перекрываться - не может. А именно про это идет речь. Qt изначально умел рисовать все сам в frame buffer (что являлось его огромным плюсом), поэтому он сам является тем оконным композитором, который должен все отобразить. А это, для перекрывающихся виджетов, можно сделать только в один поток.

PS: Да, и нарямую вызывать метод paintEvent чревато, так как GUI элемент может быть и удален ненароком в момент вызова, отображаем то асинхронно. Лучше уж QImage держать независимо от GUI в отдельном дереве рендерера.
Когда вызывается paintEvent уже никто удалиться не может, потому что он может вызывается только из того самого рендерера, который должен быть в конечном итоге однопоточным. И именно он хранит иерархию отображаемых объектов.

Многопоточный GUI подразумевает независимую реакцию элементов GUI на события, без явных взаимных блокировок друг друга и рендерера.
Ok, с отображением вопросы отпали, остались с реакцией. :)
А что в Qt принципиально не позволяет сделать независимую реакцию элементов?


Название: Re: Тестовое задание на программиста С++/Qt компания некстерс
Отправлено: ssoft от Сентябрь 06, 2016, 08:44
Нет. Если элементы ветвей могут перекрываться - не может. А именно про это идет речь. Qt изначально умел рисовать все сам в frame buffer (что являлось его огромным плюсом), поэтому он сам является тем оконным композитором, который должен все отобразить. А это, для перекрывающихся виджетов, можно сделать только в один поток.

Если не нужно смешивать цвета, то можно совместить QImage параллельно, без потри качества (обычно в GUI цвета не смешивают). Если же есть необходимость смешивания, то можно использовать многопроходный алгоритм, смешивая одно и тоже несколько раз с разными параметрами. По такому принципу, например, трехмерные сцены в OpenGL отображаются (как с потерей качества, так и без), так как в зависимости от трансформации сцены имеет место разный порядок видимости объектов, а их упорядочивание слишком ресурсоемко и не всегда возможно. Однако, нужно отдать должное последовательное смешивание буферов иногда может оказаться и эффективнее. Думаю, что Вы это и без меня знаете  ;D.

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

Это реализация иерархии отображаемых объектов в виде неотъемлемой части рендерера). А как же модель данных и возможность отображения их одновременно в разных видах? И если говорить относительно принципов построения GUI в Qt, то иерархия там представлена отношением Parent/Child, где дочерние элементы являются частью родительского, а не рендерера.

Ok, с отображением вопросы отпали, остались с реакцией. :)
А что в Qt принципиально не позволяет сделать независимую реакцию элементов?

Принципиально можно переделать всё). Напишу, что мешает в Qt C++, QML здесь не касаюсь.

  • Во-первых, иерархия объектов в виде Parent/Child позволяет осуществлять непосредственный доступ по незащищенному голому указателю, как к родителю, так и дочерним элементам.
  • Во-вторых, иерархия объектов в виде Parent/Child реализует взаимосвязь, когда родитель управляет временем жизни дочерних элементов.
  • Во-третьих, иерархия объектов в виде Parent/Child и прямой доступ к родительскому и дочерним элементам требует обеспечения "правильного" порядка обработки событий (например, сначала HoverLeave для одного, затем HoverEnter для другого, а не вразнобой), иначе взаимосвязанные элементы дерева будут находиться в несогласованном состоянии.
  • Во-четвертых, система фильтрации событий QEvent, которая позволяет напрямую перехватывать сообщения, и может быть использована в том числе в отношении один фильтр ко многим GUI.

Чтобы все это работало без проблем, вводится ограничение, чтобы все дерево иерархии Parent/Child соотносилось с одним потоком обработки сообщений. Может я еще что-то не написал, но все вышеперечисленное относится к базовым концепциям библиотеки Qt и переделывать это никто не будет).

Чтобы реализовать многопоточный GUI необходимо иметь иерархию в виде дерева независимых элементов, без отношения Parent/Child; желательно пользоваться не голыми указателями, а хотя бы shared/weak для контроля времени жизни GUI; изменить систему фильрации - вместо объектов использовать функторы, например; желательно не иметь явного соотношения GUI с потоком обработки, а гарантировать активность GUI не более чем в одном потоке.


Название: Re: Тестовое задание на программиста С++/Qt компания некстерс
Отправлено: Old от Сентябрь 06, 2016, 09:31
Если не нужно смешивать цвета, то можно совместить QImage параллельно, без потри качества (обычно в GUI цвета не смешивают). Если же есть необходимость смешивания, то можно использовать многопроходный алгоритм, смешивая одно и тоже несколько раз с разными параметрами. По такому принципу, например, трехмерные сцены в OpenGL отображаются (как с потерей качества, так и без), так как в зависимости от трансформации сцены имеет место разный порядок видимости объектов, а их упорядочивание слишком ресурсоемко и не всегда возможно. Однако, нужно отдать должное последовательное смешивание буферов иногда может оказаться и эффективнее. Думаю, что Вы это и без меня знаете  ;D.
Вот как раз в современном GUI альфа канал обязателен, а вот 3-х мерные трансформации не очень. Надеюсь пока. :)

Это реализация иерархии отображаемых объектов в виде неотъемлемой части рендерера). А как же модель данных и возможность отображения их одновременно в разных видах? И если говорить относительно принципов построения GUI в Qt, то иерархия там представлена отношением Parent/Child, где дочерние элементы являются частью родительского, а не рендерера.
Дочерние являются частью родительского и легко могут рисоваться в других потоках, а вот top-level окна как раз являются элементами рендерера, и  именно он их отображает, и только в один поток. Еще раз напомню, Qt изначально умел рисовать все сам в frame buffer и этот рендерер иметь был обязан.

Чтобы все это работало без проблем, вводится ограничение, чтобы все дерево иерархии Parent/Child соотносилось с одним потоком обработки сообщений. Может я еще что-то не написал, но все вышеперечисленное относится к базовым концепциям библиотеки Qt и переделывать это никто не будет).
Да не надо ничего переделывать. :)
Qt не является (и наверное не задумывался), как многопоточный GUI (в том виде, как вы его видите).
Но на нем можно решать задачи многопоточного GUI, с ограничениями, оговорками, но можно. Нет нужды постоянно создавать и уничтожать виджеты из разных потоков, но бывает потребность рендерить виджет в другом потоке - в Qt это возможно. Нужна быстрая реакция на спонтанные события, не выполняйте "тяжелую" обработку в главном потоке. И т.д.

Если вам ехать, а не шашечки, то Qt можно для этого помучить. Это будет не так безопасно и красиво, но работать будет. :)


Название: Re: Тестовое задание на программиста С++/Qt компания некстерс
Отправлено: ssoft от Сентябрь 06, 2016, 10:20
 
Если вам ехать, а не шашечки, то Qt можно для этого помучить. Это будет не так безопасно и красиво, но работать будет. :)

Согласен, для статической структуры GUI будет работать и так, но к сожалению это не мой случай  :D. В моих задачах (связаны с почти realtime регистрацией наблюдений) постоянно меняется как состав данных, так и их атрибуты, да и к тому же GUI является частью 3D сцены, так что 3D трансформации уже рулят  ;D.


Название: Re: Тестовое задание на программиста С++/Qt компания некстерс
Отправлено: __Heaven__ от Сентябрь 12, 2016, 12:56
Ребят, а в 7, ведь не от компиля зависит, вроде как.
У нас конструктор копирования может быть вызван неявным образом, отсутствует указание explicit.
Также конструктор копирования применяется для создания объекта, а оператор присваивания работает с существующим объектом.
В нашем же случае объект создаётся, потому и происходит вызов копирования.

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


Название: Re: Тестовое задание на программиста С++/Qt компания некстерс
Отправлено: Alex Custov от Сентябрь 12, 2016, 16:40
Но, признаться честно, до сегодняшнего дня я думал, что сначала создаётся объект, а потом производится вызов оператора присваивания.
Поправьте меня, если я не прав.

Насколько я помню, могу ошибаться, это implementation-defined с упором на зависимость от уровня оптимизации. Простейшие конструкции типа A a = f(); из задания (при этом f() - тоже простейшая) оптимизатор может заменить на прямое конструирование.


Название: Re: Тестовое задание на программиста С++/Qt компания некстерс
Отправлено: __Heaven__ от Сентябрь 12, 2016, 17:31
Эта штука называется copy initialization (http://en.cppreference.com/w/cpp/language/copy_initialization)


Название: Re: Тестовое задание на программиста С++/Qt компания некстерс
Отправлено: __Heaven__ от Сентябрь 12, 2016, 17:55
И на закуску :)
https://ideone.com/yAanDi (https://ideone.com/yAanDi)
Код
C++ (Qt)
#include <iostream>
 
class A{
public:
A(){}
explicit A(const A &other){ std::cout << "Copy\n";}
~A(){}
 
A &operator= (const A &other){
std::cout << "Assign\n";
return *this;
}
};
 
 
int main() {
A foo;
A bar = foo;
bar = foo;
return 0;
}
Цитировать
prog.cpp: In function 'int main()':
prog.cpp:18:10: error: no matching function for call to 'A::A(A&)'
  A bar = foo;
          ^
prog.cpp:5:2: note: candidate: A::A()
  A(){}
  ^
prog.cpp:5:2: note:   candidate expects 0 arguments, 1 provided
Убрав explicit получим copy assign


Название: Re: Тестовое задание на программиста С++/Qt компания некстерс
Отправлено: nsxwrs от Сентябрь 14, 2016, 00:40
Вообще, знать что выдаст конструкция ++i + ++i + i++ это охренительно важно для работы программистом.
Избегать таких конструкций и писать, чтоб всё было однозначно ни в коем случае нельзя.
C начальным значением 0 получается 5, а при его отсутствии - 0. Кто объяснит почему?
https://ideone.com/6jSkPO


Название: Re: Тестовое задание на программиста С++/Qt компания некстерс
Отправлено: kambala от Сентябрь 14, 2016, 00:51
первый случай объясняется элементарно при знании работы операторов инкремента: 1 + 2 + 2; во втором случае результат неопределен, т.к. начальное значение — мусор (произвольное число).


Название: Re: Тестовое задание на программиста С++/Qt компания некстерс
Отправлено: kai666_73 от Сентябрь 14, 2016, 10:08
Вообще, знать что выдаст конструкция ++i + ++i + i++ это охренительно важно для работы программистом.
Избегать таких конструкций и писать, чтоб всё было однозначно ни в коем случае нельзя.
C начальным значением 0 получается 5, а при его отсутствии - 0. Кто объяснит почему?
https://ideone.com/6jSkPO

Формально, результат этой конструкции undefined
и, соответственно, за использование подобных конструкций программисту надо руки отрубать... и ноги, на всякий случай )


Название: Re: Тестовое задание на программиста С++/Qt компания некстерс
Отправлено: Авварон от Сентябрь 26, 2016, 20:05
Я мимокрокодил, но хочу добавить, что в 7 ещё и RVO применилась, что не всегда бывает.