Comments 48
Согласен, к сожалению, C++ не лишен недостатков. Все таки не хватает ему некой «гибкости». Но это не мешает ему быть самым универсальным языком.
>Согласен, к сожалению, C++ не лишен недостатков.
А я не согласен, всё что написано полный бред.
Во-первых есть принципы ООП
butunclebob.com/ArticleS.UncleBob.PrinciplesOfOod
Во-вторых то чего якобы нет в C++ называется шаблонами проектирования
А я не согласен, всё что написано полный бред.
Во-первых есть принципы ООП
butunclebob.com/ArticleS.UncleBob.PrinciplesOfOod
Во-вторых то чего якобы нет в C++ называется шаблонами проектирования
например sourcemaking.com/design_patterns
В третьих, многие шаблоны проектирования могут реализовываться не только полиморфизмом, но и с помощью техники обобщённого программирования (template C++).
P.S. между прочим в Qt нарушили кучу принципов ООП, то что C++ позволял делать решили реализовать метакомпилятором, про принципы вообще уж молчу. На самом деле C++ очень даже подходит, только вот пользоваться им и техникой ООП многие не умеют.
В третьих, многие шаблоны проектирования могут реализовываться не только полиморфизмом, но и с помощью техники обобщённого программирования (template C++).
P.S. между прочим в Qt нарушили кучу принципов ООП, то что C++ позволял делать решили реализовать метакомпилятором, про принципы вообще уж молчу. На самом деле C++ очень даже подходит, только вот пользоваться им и техникой ООП многие не умеют.
Может быть дело в том, что в нем, в отличие, например от Java нет встроенных визуальных компонентов и их надо придумывать ручками ил пользоваться билдером/кьютом/другими имярек?
Очень даже нарушали, не веришь, почитай «Быстрая разработка программ. Принципы, примеры, практика» автор Р.К. Мартин. В книге учат не только понимать, что принципы ООП нарушаются, но и измерять в цифрах насколько они нарушены, строить по ним графики и так далее. Про template лучше всего наверное Александреску курить, что-нибудь типа «Современое проектирование на C++», и другое.
Давайте покритикуем C++ на примере других языков. Возьмём хотя бы C#, он имеет систему событий. Иными словами есть ключевые слова для этого. Но что это такое? А это Multicast Delegate. И давайте упрекайте C++ в том, что не знаете после этого, что такое Observer. Со свойствами ещё веселее, будут тупо сделаны две функции, те самые accessor и mutator.
Вернёмся к статье, там критика про иерархии и прочее. Чем не нравится Composite и прочие шаблоны проектирование? Чем не нравятся умные указатели? В итоге мы имеем не плохую совместимость с GUI, а просто лень в изучении ООП и обыкновенное незнание его. Ну и конечно одна от балды написанная виртуальная функция сразу доказала всю мерзость C++ как языка.
Давайте покритикуем C++ на примере других языков. Возьмём хотя бы C#, он имеет систему событий. Иными словами есть ключевые слова для этого. Но что это такое? А это Multicast Delegate. И давайте упрекайте C++ в том, что не знаете после этого, что такое Observer. Со свойствами ещё веселее, будут тупо сделаны две функции, те самые accessor и mutator.
Вернёмся к статье, там критика про иерархии и прочее. Чем не нравится Composite и прочие шаблоны проектирование? Чем не нравятся умные указатели? В итоге мы имеем не плохую совместимость с GUI, а просто лень в изучении ООП и обыкновенное незнание его. Ну и конечно одна от балды написанная виртуальная функция сразу доказала всю мерзость C++ как языка.
>Да да, многие паттерны просто добавляют тормозов в реальности.
Не паттерны добавляют тормозов, а использование полиморфизма в них (то есть виртуальные функции), особенно его неоправданно высокий уровень. Именно поэтому я и упомянул о template в C++. Шаблон (паттерн) проектирования ООП в общем случае это некая идея, она жёстко от реализации не зависит.
Хотя тормоза это сильно сказано, я бы сказал вызов происходит немного медленнее. Но C++ часто предоставляет такой вот выбор, встроенная функция (больше объём скомпилированного кода) или нет, виртуальная или нет (например template при тех же возможностях паттернов нет потери производительности), и так далее.
>С меня в свое время хватило ковыряния в ZendFramework чтобы понять, что ООП ради ООП не ведет ни к чему кроме создания тонны лишнего кода.
>>Zend Framework — это свободный каркас на PHP для разработки веб-приложений и веб-сервисов.
Про него ничего не знаю, я C++ обсуждал. Причём здесь какой-то фреймворк и вообще другой язык?
>Плюсы всё же компилируемый язык и витать в облаках патернов тут не позволяет низкоуровневость
Позволяет, но это зависит от уровня умений программистов. Инкапсуляция, наследование и полиморфизм это только начало, наиболее мелкие кирпичики ООП. Знать и использовать их вовсе не значит уметь программировать в стиле ООП.
Не паттерны добавляют тормозов, а использование полиморфизма в них (то есть виртуальные функции), особенно его неоправданно высокий уровень. Именно поэтому я и упомянул о template в C++. Шаблон (паттерн) проектирования ООП в общем случае это некая идея, она жёстко от реализации не зависит.
Хотя тормоза это сильно сказано, я бы сказал вызов происходит немного медленнее. Но C++ часто предоставляет такой вот выбор, встроенная функция (больше объём скомпилированного кода) или нет, виртуальная или нет (например template при тех же возможностях паттернов нет потери производительности), и так далее.
>С меня в свое время хватило ковыряния в ZendFramework чтобы понять, что ООП ради ООП не ведет ни к чему кроме создания тонны лишнего кода.
>>Zend Framework — это свободный каркас на PHP для разработки веб-приложений и веб-сервисов.
Про него ничего не знаю, я C++ обсуждал. Причём здесь какой-то фреймворк и вообще другой язык?
>Плюсы всё же компилируемый язык и витать в облаках патернов тут не позволяет низкоуровневость
Позволяет, но это зависит от уровня умений программистов. Инкапсуляция, наследование и полиморфизм это только начало, наиболее мелкие кирпичики ООП. Знать и использовать их вовсе не значит уметь программировать в стиле ООП.
Не согласен с Вами по ряду высказываний.
— Например реализовать систему делегатов и событий для С++ не составляет большого труда, благо получить адрес объекта и адрес метода в С++ можно без проблем и на уровне библиотеки это реализуется в виде 200-300 строк кода (если без особых наворотов)
— По поводу свойств в С++ тоже не все однозначно, например Рихтер в последней книге CLR via C# утверждает что свойства вообще лучше не использовать и их не следовало включать в C#, так не ужели тогда есть эта необходимость в С++.
— И по поводу ООП. Думаю, иногда лучше просто решить поставленную задачу, а не строить «космолет», если вы не пишите библиотек для дальнейшей дистрибуции, то в ряде случаев ООП больше головная боль, чем полезный инструмент. Например, нам надо сложить два числа и результат вывести в терминал.
На С/C++:
#include <stdio.h>
int main()
{
int a, b;
scanf("%i %i", &a, &b);
printf("%i\n", a + b);
return 0;
}
На Java:
import java.io.*;
import java.util.*;
class solver
{
public static void main(String[] args) throws IOException
{
BufferedReader in = new BufferedReader(new InputStreamReader(System.in));
PrintWriter out = new PrintWriter(new OutputStreamWriter(System.out));
StringTokenizer str;
str = new StringTokenizer(in.readLine());
int a = Integer.parseInt(str.nextToken());
str = new StringTokenizer(in.readLine());
int b = Integer.parseInt(str.nextToken());
out.println(a + b);
out.flush();
}
}
Какой случай вам больше нравится? Где ООП или где СП? А где код работает быстрее?
— Например реализовать систему делегатов и событий для С++ не составляет большого труда, благо получить адрес объекта и адрес метода в С++ можно без проблем и на уровне библиотеки это реализуется в виде 200-300 строк кода (если без особых наворотов)
— По поводу свойств в С++ тоже не все однозначно, например Рихтер в последней книге CLR via C# утверждает что свойства вообще лучше не использовать и их не следовало включать в C#, так не ужели тогда есть эта необходимость в С++.
— И по поводу ООП. Думаю, иногда лучше просто решить поставленную задачу, а не строить «космолет», если вы не пишите библиотек для дальнейшей дистрибуции, то в ряде случаев ООП больше головная боль, чем полезный инструмент. Например, нам надо сложить два числа и результат вывести в терминал.
На С/C++:
#include <stdio.h>
int main()
{
int a, b;
scanf("%i %i", &a, &b);
printf("%i\n", a + b);
return 0;
}
На Java:
import java.io.*;
import java.util.*;
class solver
{
public static void main(String[] args) throws IOException
{
BufferedReader in = new BufferedReader(new InputStreamReader(System.in));
PrintWriter out = new PrintWriter(new OutputStreamWriter(System.out));
StringTokenizer str;
str = new StringTokenizer(in.readLine());
int a = Integer.parseInt(str.nextToken());
str = new StringTokenizer(in.readLine());
int b = Integer.parseInt(str.nextToken());
out.println(a + b);
out.flush();
}
}
Какой случай вам больше нравится? Где ООП или где СП? А где код работает быстрее?
>Например реализовать систему делегатов и событий для С++ не составляет большого труда, благо получить адрес объекта и адрес метода в С++ можно без проблем
А я где-то говорил, что это запредельно сложно? Написал же — шаблон проектирования — Observer. Кстати, в связи с адресами вспомнилось, что в книге про Qt писали. (мой вольный перевод :) Им якобы обратный вызов извратской техникой казался. И сигнатуру не передашь, и в целом неудобно.
Потому они метакомпилятор (moc) и сделали сверху. Иными словами обратный вызов им не нравился, а возится с шаблонами проектирования, которые лишены этих недостатков не стали. Но как я уже говорил, Qt очень хорош для быстрого и качественного результата, только это не образец для обучения ООП, во многих смыслах всё совсем наоборот.
>Какой случай вам больше нравится? Где ООП или где СП? А где код работает быстрее?
Честно тебе скажу, второй твой пример с ООП не имеет ничего общего, как впрочем и первый. У тебя просто всё запихано в одну функцию, которая лежит в классе. Но ключевое слово class само по себе не делает стиль объектно-ориентированным.
Если не считать этого грубого примитива, когда процедурное программирование пытаются выдать за ООП, я бы сказал так. ООП даёт преимущество на относительно больших проектах, а учится приходится на маленьких. А маленькое очень похоже на «сложение двух чисел».
Мы пытаемся сложить два числа, и одновременно применить ООП. И тут попадаем в ловушку собственных заблуждений о том чего достигли. Потому чтобы осилить путь ООП нужно очень постараться, читать книги, писать код. Если же не охота, так не проблема, просто стиль будет называться не объектно-ориентированным, и его не надо путать с ним.
А я где-то говорил, что это запредельно сложно? Написал же — шаблон проектирования — Observer. Кстати, в связи с адресами вспомнилось, что в книге про Qt писали. (мой вольный перевод :) Им якобы обратный вызов извратской техникой казался. И сигнатуру не передашь, и в целом неудобно.
Потому они метакомпилятор (moc) и сделали сверху. Иными словами обратный вызов им не нравился, а возится с шаблонами проектирования, которые лишены этих недостатков не стали. Но как я уже говорил, Qt очень хорош для быстрого и качественного результата, только это не образец для обучения ООП, во многих смыслах всё совсем наоборот.
>Какой случай вам больше нравится? Где ООП или где СП? А где код работает быстрее?
Честно тебе скажу, второй твой пример с ООП не имеет ничего общего, как впрочем и первый. У тебя просто всё запихано в одну функцию, которая лежит в классе. Но ключевое слово class само по себе не делает стиль объектно-ориентированным.
Если не считать этого грубого примитива, когда процедурное программирование пытаются выдать за ООП, я бы сказал так. ООП даёт преимущество на относительно больших проектах, а учится приходится на маленьких. А маленькое очень похоже на «сложение двух чисел».
Мы пытаемся сложить два числа, и одновременно применить ООП. И тут попадаем в ловушку собственных заблуждений о том чего достигли. Потому чтобы осилить путь ООП нужно очень постараться, читать книги, писать код. Если же не охота, так не проблема, просто стиль будет называться не объектно-ориентированным, и его не надо путать с ним.
>Им якобы обратный вызов извратской техникой казался
Ну собственно никакого изврата не вижу. вот простейшая сигнатура делегата:
Ну собственно никакого изврата не вижу. вот простейшая сигнатура делегата:
template class Delegate
{
private:
struct T { };
typedef void (T::*PMETHOD) (TArg);
protected:
T* m_pObject;
PMETHOD m_pMethod;
public:
Delegate();
template Delegate(TClass* pObject, void (TClass::*pMethod) (TArg));
Delegate(const Delegate& delegate);
~Delegate();
Delegate& operator = (const Delegate& delegate);
bool operator == (const Delegate& delegate);
bool operator != (const Delegate& delegate);
void operator () (TArg arg);
void Invoke(TArg arg);
bool IsNullOrEmpty();
};
Чего уж такого ужасного, не понятно.
>Честно тебе скажу, второй твой пример с ООП не имеет ничего общего, как впрочем и первый
Смысл был не в том, чтобы писать какую-то навороченную архитектуру, а в том, что показать как эти архитектуры применяются для решения простых задач:
str = new StringTokenizer(in.readLine());
int a = Integer.parseInt(str.nextToken());
Слишком сурово и расточительно для элементарных задач плодить объекты классов, лишь только для того, чтобы они были, т.е. не стоит плодить лишних сущностей там, где их не должно быть.>Слишком сурово и расточительно для элементарных задач плодить объекты классов
В книгах по ООП сразу пишут, различайте классы ADT (Abstract Data Types) и классы участвующие в построении различных объектно-ориентированных конструкций. Хотя яву не изучал, но мне думается в примере слишком много лишнего просто для прикола.
В глаза сразу бросается out, который используется не там где объявляется, и многократно повторяющийся new для получения строк. Ну тебе виднее, если бы это был .NET, я бы сказал, что это намеренное издевательство :), а так не знаю.
>Чего уж такого ужасного, не понятно.
Какой-то он недоделанный, впрочем это не столь важно. В Qt пошли по пути сокрытия деталей. В итоге там всё равно после MOC получится обычный C++ код. Мне такое положение дел не очень нравится.
Хотя если подумать для C++ столько сторонних библиотек, и каждая имеет какой-то свой стиль. Здесь уж без разницы, что сам пишешь, то и будет. Нет определяющего общий стиль фреймворка и это не так плохо, хотя думать на проблемой выбора своего стиля надо больше.
В книгах по ООП сразу пишут, различайте классы ADT (Abstract Data Types) и классы участвующие в построении различных объектно-ориентированных конструкций. Хотя яву не изучал, но мне думается в примере слишком много лишнего просто для прикола.
В глаза сразу бросается out, который используется не там где объявляется, и многократно повторяющийся new для получения строк. Ну тебе виднее, если бы это был .NET, я бы сказал, что это намеренное издевательство :), а так не знаю.
>Чего уж такого ужасного, не понятно.
Какой-то он недоделанный, впрочем это не столь важно. В Qt пошли по пути сокрытия деталей. В итоге там всё равно после MOC получится обычный C++ код. Мне такое положение дел не очень нравится.
Хотя если подумать для C++ столько сторонних библиотек, и каждая имеет какой-то свой стиль. Здесь уж без разницы, что сам пишешь, то и будет. Нет определяющего общий стиль фреймворка и это не так плохо, хотя думать на проблемой выбора своего стиля надо больше.
>я бы сказал, что это намеренное издевательство :)
Ради интереса, можно глянуть здесь примеры «А+В» для различных ЯП, если интересно A+B.
>Нет определяющего общий стиль фреймворка и это не так плохо, хотя думать на проблемой выбора своего стиля надо больше.
Для С++ это всегда было большой проблемой, если используешь несколько сторонних библиотек в проекте, то гарантированна головная боль по согласованию стилей. Но больше всего мне не нравятся различные подходы к управлению памятью почти в каждой библиотеке, написанной на С++.
Ради интереса, можно глянуть здесь примеры «А+В» для различных ЯП, если интересно A+B.
>Нет определяющего общий стиль фреймворка и это не так плохо, хотя думать на проблемой выбора своего стиля надо больше.
Для С++ это всегда было большой проблемой, если используешь несколько сторонних библиотек в проекте, то гарантированна головная боль по согласованию стилей. Но больше всего мне не нравятся различные подходы к управлению памятью почти в каждой библиотеке, написанной на С++.
>Ради интереса, можно глянуть здесь примеры «А+В» для различных ЯП, если интересно A+B.
Посмотрел, хотя примеры неодинаковы по смыслу. В С++ просто берём значения из потока консоли. А в C# берём и делим строку на массив строк с разделяющим символом — пробел. Потом берём первую строку из него и преобразуем в целочисленное одним из нескольких равнозначных способов доступных в C#.
Ладно хоть сами вызовы статические, чего уже нельзя сказать о примерах с Java. Я всё же за то, чтобы в сравнениях использовались более ли менее одинаковые техники.
Посмотрел, хотя примеры неодинаковы по смыслу. В С++ просто берём значения из потока консоли. А в C# берём и делим строку на массив строк с разделяющим символом — пробел. Потом берём первую строку из него и преобразуем в целочисленное одним из нескольких равнозначных способов доступных в C#.
Ладно хоть сами вызовы статические, чего уже нельзя сказать о примерах с Java. Я всё же за то, чтобы в сравнениях использовались более ли менее одинаковые техники.
Пометьте статью, как перевод.
Оригинал — arxiv.org/html/cs.PL/0001003
Оригинал — arxiv.org/html/cs.PL/0001003
Спасибо. Почему-то не получается отметить статью, как перевод. Хабр переадресовывает на создание нового топика.
напишите честно — «я не осилил QT»
а то С++ им видите ли не подходит
З.Ы.
вообще я согласен что С++ УГ, но я уже сделал достаточно гуёвых прог на С++ под несколько платформ чтобы с уверенностью сказать вам вполне подходит
а то С++ им видите ли не подходит
З.Ы.
вообще я согласен что С++ УГ, но я уже сделал достаточно гуёвых прог на С++ под несколько платформ чтобы с уверенностью сказать вам вполне подходит
Это вообще-то перевод далеко не «свежей» статьи.
«я не осилил Qt»
Ну так ведь там же moc и прочая нестандартная лабудень на макросах, да? Что, впрочем, не мешает Qt быть замечательным тулкитом.
>напишите честно — «я не осилил QT»
это следует написать Вам
это следует написать Вам
А еще посмотрите на MFC. Если не переходить определенные границы, Ваши утверждения оч спорны. (Сразу скажу, что с этой библиотекой намаялся за несколько лет)
Так какой язык то использовать предлагаете то?
C++ много для чего не подходит.
Например, он не варит по утрам кофе. Не отводит детей в детский сад. А ведь столько ещё в мире вещей, которые C++ почему-то не делает. Меня всегда расстраивало, что C++ за меня не думает, и не выполняет всю работу.
Да нет, за сиплюсплюсеров язык как раз и думает, иначе откуда столько кривых велосипедов?
Бред полный, к примеру идеи заложенные в wtl очень даже неплохо работают. Сколько работал над GUI, проблем не замечал. Просто нужно знать язык на котором программируешь.
Ребят, я конечно все понимаю, опыт и так далее, однако есть одно «но».
Никто из тех, кто заявил, что статья «бред», не привёл ни одного аргумента в пользу своего весомого мнения. Да что там, никто даже и не прокомментировал пойнты из статьи.
Хватит устраивать детский сад на Хабре.
И по поводу статьи: с основными пойнтами согласен, однако (а) все это можно преодолеть (что и демонстрирует мильён GUI-фреймворков на Си++), (б) этот мильён фреймворков «достаточно хорош» для своих задач.
Никто из тех, кто заявил, что статья «бред», не привёл ни одного аргумента в пользу своего весомого мнения. Да что там, никто даже и не прокомментировал пойнты из статьи.
Хватит устраивать детский сад на Хабре.
И по поводу статьи: с основными пойнтами согласен, однако (а) все это можно преодолеть (что и демонстрирует мильён GUI-фреймворков на Си++), (б) этот мильён фреймворков «достаточно хорош» для своих задач.
Для вдумчивого ознакомления тему надо раздробить на логически автономные элементы и обсуждать каждый в отдельности. По результатам комментирования можно добавлять в основной текст, прийти к какому-либо единому мнению, основанному на опыте тех, кто добился хороших результатов.
Например, мусоросборка и GUI. Большая тема. Мне, например, есть что сказать по этому поводу.
Здесь же получается каша из холивара и обобщённых мнений, и у меня нет желания писать сюда в комментарии какой-либо серьёзный материал.
Например, мусоросборка и GUI. Большая тема. Мне, например, есть что сказать по этому поводу.
Здесь же получается каша из холивара и обобщённых мнений, и у меня нет желания писать сюда в комментарии какой-либо серьёзный материал.
Может быть дело в том, что в нем, в отличие, например от Java нет встроенных визуальных компонентов и их надо придумывать ручками ил пользоваться билдером/кьютом/другими имярек?
Можно делать, а можно стандартными пользоваться:
www.cplusplus.com/reference/std/memory/auto_ptr/
www.boost.org/doc/libs/1_43_0/libs/smart_ptr/smart_ptr.htm
Между прочим в том же .NET сборщик мусора не из воздуха берётся.
www.cplusplus.com/reference/std/memory/auto_ptr/
www.boost.org/doc/libs/1_43_0/libs/smart_ptr/smart_ptr.htm
Между прочим в том же .NET сборщик мусора не из воздуха берётся.
Перейди хотя бы по первой ссылке, это STL, она должна быть во всех реализациях C++. Сборка мусора — garbage collection, и часть этой системы умные указатели. В вики описаны основные принципы.
ru.wikipedia.org/wiki/Сборка_мусора
Если говорить в целом, то сборка мусора это управление памятью (memory) и автоматическое удаление объектов, когда их больше нельзя использовать, а значит и незачем держать в памяти. На C++ предоставляется выбор, или ручное управление памятью, или использование стандартных, сторонних и самописных реализаций.
Ссылки между прочим часто считают для того, чтобы удалить объект, когда их количество становится равно нулю. Давайте всё же не будем судить о C++ на основе других языков и реализаций стандартных библиотек, дескать те истинные сборщики мусора, а вот это что-то не то хотя бы потому что оно на C++, а не на ххх.
ru.wikipedia.org/wiki/Сборка_мусора
Если говорить в целом, то сборка мусора это управление памятью (memory) и автоматическое удаление объектов, когда их больше нельзя использовать, а значит и незачем держать в памяти. На C++ предоставляется выбор, или ручное управление памятью, или использование стандартных, сторонних и самописных реализаций.
Ссылки между прочим часто считают для того, чтобы удалить объект, когда их количество становится равно нулю. Давайте всё же не будем судить о C++ на основе других языков и реализаций стандартных библиотек, дескать те истинные сборщики мусора, а вот это что-то не то хотя бы потому что оно на C++, а не на ххх.
можно конечно расписать по каждому пункту, например «Нет синтаксических средств переключения событий» я вообще не понял — автор, что, удивляется тому, что надо вручную вызвать родительскую реализацию repaint'а? И какое это имеет отношение к «переключению событий»? Что он вообще подразумевает под переключением?
В общем, такое ощущение, что оригинальный текст писал какой-то школьник.
Имхо, хорошим опровержением статье в целом является сам факт наличия такой библиотеки, как Qt.
В общем, такое ощущение, что оригинальный текст писал какой-то школьник.
Имхо, хорошим опровержением статье в целом является сам факт наличия такой библиотеки, как Qt.
посмотрел на дату оригинального текста, 95-й год, вопросы снимаются, тогда на С++ действительно не умели писать…
тогда как-то глупо было вобще перевод статьи этой выкладывать )
Хотя почему такая статья понятно, в то время нормальных тулкитов не было. C# тоже еще не появился, а Java только только делает первые шаги. Единственным средсвом был С/C++.
Хотя почему такая статья понятно, в то время нормальных тулкитов не было. C# тоже еще не появился, а Java только только делает первые шаги. Единственным средсвом был С/C++.
Действительно — okmij.org/ftp/cpp-digest/CPP-GUI-mismatch.html
Ну тогда и обсуждать нечего.
ISO/IEC 14882:1998 C++
ISO/IEC 14882:2003 C++
По мне так нет смысла опускаться ниже 1998 года. Это не обязательно школьник писал, просто человек из далёкого прошлого, когда мир был другим и знаний было накоплено меньше.
Ну тогда и обсуждать нечего.
ISO/IEC 14882:1998 C++
ISO/IEC 14882:2003 C++
По мне так нет смысла опускаться ниже 1998 года. Это не обязательно школьник писал, просто человек из далёкого прошлого, когда мир был другим и знаний было накоплено меньше.
>Имхо, хорошим опровержением статье в целом является сам факт наличия такой библиотеки, как Qt.
угу. С костылём под названием MOC
угу. С костылём под названием MOC
Sign up to leave a comment.
Почему C++ не подходит для написания графических пользовательских интерфейсов