Pull to refresh

Comments 48

Согласен, к сожалению, C++ не лишен недостатков. Все таки не хватает ему некой «гибкости». Но это не мешает ему быть самым универсальным языком.
>Согласен, к сожалению, C++ не лишен недостатков.

А я не согласен, всё что написано полный бред.

Во-первых есть принципы ООП
butunclebob.com/ArticleS.UncleBob.PrinciplesOfOod

Во-вторых то чего якобы нет в C++ называется шаблонами проектирования
например sourcemaking.com/design_patterns

В третьих, многие шаблоны проектирования могут реализовываться не только полиморфизмом, но и с помощью техники обобщённого программирования (template C++).

P.S. между прочим в Qt нарушили кучу принципов ООП, то что C++ позволял делать решили реализовать метакомпилятором, про принципы вообще уж молчу. На самом деле C++ очень даже подходит, только вот пользоваться им и техникой ООП многие не умеют.
Может быть дело в том, что в нем, в отличие, например от Java нет встроенных визуальных компонентов и их надо придумывать ручками ил пользоваться билдером/кьютом/другими имярек?
Не проблема пользоваться GTK+, Qt GUI, wxWidgets и другими. Другое дело, что если заниматься только формошлёпством, то так ООП не изучишь.
Ничего они не нарушали, ООП это не священная корова. В те времена, когда создавался moc, шаблоны в плюсах еще были зелеными и плохо работающими. А сейчас он просто удобно упрощает многие вещи и потому смысл его убирать, если он прекрасно работает
Очень даже нарушали, не веришь, почитай «Быстрая разработка программ. Принципы, примеры, практика» автор Р.К. Мартин. В книге учат не только понимать, что принципы ООП нарушаются, но и измерять в цифрах насколько они нарушены, строить по ним графики и так далее. Про template лучше всего наверное Александреску курить, что-нибудь типа «Современое проектирование на C++», и другое.

Давайте покритикуем C++ на примере других языков. Возьмём хотя бы C#, он имеет систему событий. Иными словами есть ключевые слова для этого. Но что это такое? А это Multicast Delegate. И давайте упрекайте C++ в том, что не знаете после этого, что такое Observer. Со свойствами ещё веселее, будут тупо сделаны две функции, те самые accessor и mutator.

Вернёмся к статье, там критика про иерархии и прочее. Чем не нравится Composite и прочие шаблоны проектирование? Чем не нравятся умные указатели? В итоге мы имеем не плохую совместимость с GUI, а просто лень в изучении ООП и обыкновенное незнание его. Ну и конечно одна от балды написанная виртуальная функция сразу доказала всю мерзость C++ как языка.
Давайте не будем впадать в ООП головного мозга. С меня в свое время хватило ковыряния в ZendFramework чтобы понять, что ООП ради ООП не ведет ни к чему кроме создания тонны лишнего кода. Плюсы всё же компилируемый язык и витать в облаках патернов тут не позволяет низкоуровневость. Да да, многие паттерны просто добавляют тормозов в реальности.
>Да да, многие паттерны просто добавляют тормозов в реальности.

Не паттерны добавляют тормозов, а использование полиморфизма в них (то есть виртуальные функции), особенно его неоправданно высокий уровень. Именно поэтому я и упомянул о 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();
}
}

Какой случай вам больше нравится? Где ООП или где СП? А где код работает быстрее?
>Например реализовать систему делегатов и событий для С++ не составляет большого труда, благо получить адрес объекта и адрес метода в С++ можно без проблем

А я где-то говорил, что это запредельно сложно? Написал же — шаблон проектирования — 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++ столько сторонних библиотек, и каждая имеет какой-то свой стиль. Здесь уж без разницы, что сам пишешь, то и будет. Нет определяющего общий стиль фреймворка и это не так плохо, хотя думать на проблемой выбора своего стиля надо больше.
>я бы сказал, что это намеренное издевательство :)
Ради интереса, можно глянуть здесь примеры «А+В» для различных ЯП, если интересно A+B.

>Нет определяющего общий стиль фреймворка и это не так плохо, хотя думать на проблемой выбора своего стиля надо больше.
Для С++ это всегда было большой проблемой, если используешь несколько сторонних библиотек в проекте, то гарантированна головная боль по согласованию стилей. Но больше всего мне не нравятся различные подходы к управлению памятью почти в каждой библиотеке, написанной на С++.
>Ради интереса, можно глянуть здесь примеры «А+В» для различных ЯП, если интересно A+B.

Посмотрел, хотя примеры неодинаковы по смыслу. В С++ просто берём значения из потока консоли. А в C# берём и делим строку на массив строк с разделяющим символом — пробел. Потом берём первую строку из него и преобразуем в целочисленное одним из нескольких равнозначных способов доступных в C#.

Ладно хоть сами вызовы статические, чего уже нельзя сказать о примерах с Java. Я всё же за то, чтобы в сравнениях использовались более ли менее одинаковые техники.

Спасибо. Почему-то не получается отметить статью, как перевод. Хабр переадресовывает на создание нового топика.
нужно спрятать этот топик и опубликовать новый, как перевод. Но комменты и оценки пропадут. В общем, учтите на будущее, изменить тип топика после публикации нельзя.
UFO just landed and posted this here
напишите честно — «я не осилил QT»
а то С++ им видите ли не подходит
З.Ы.
вообще я согласен что С++ УГ, но я уже сделал достаточно гуёвых прог на С++ под несколько платформ чтобы с уверенностью сказать вам вполне подходит
Это вообще-то перевод далеко не «свежей» статьи.
«я не осилил Qt»

Ну так ведь там же moc и прочая нестандартная лабудень на макросах, да? Что, впрочем, не мешает Qt быть замечательным тулкитом.
Это лучше чем костыль сделанный Borland в своем компиляторе C++.
>напишите честно — «я не осилил QT»

это следует написать Вам
А еще посмотрите на MFC. Если не переходить определенные границы, Ваши утверждения оч спорны. (Сразу скажу, что с этой библиотекой намаялся за несколько лет)
Так какой язык то использовать предлагаете то?
Например, он не варит по утрам кофе. Не отводит детей в детский сад. А ведь столько ещё в мире вещей, которые C++ почему-то не делает. Меня всегда расстраивало, что C++ за меня не думает, и не выполняет всю работу.
Да нет, за сиплюсплюсеров язык как раз и думает, иначе откуда столько кривых велосипедов?
Слишком много возможностей, охват большинства парадигм программирования, всё это порождает неопределённость. Синтаксис самого языка не так сложен в изучении, как умение пользоваться техниками программирования на нём.
UFO just landed and posted this here
Бред полный, к примеру идеи заложенные в wtl очень даже неплохо работают. Сколько работал над GUI, проблем не замечал. Просто нужно знать язык на котором программируешь.
Ребят, я конечно все понимаю, опыт и так далее, однако есть одно «но».

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

Хватит устраивать детский сад на Хабре.

И по поводу статьи: с основными пойнтами согласен, однако (а) все это можно преодолеть (что и демонстрирует мильён GUI-фреймворков на Си++), (б) этот мильён фреймворков «достаточно хорош» для своих задач.
Очередной неосилятор. Всё там прекрасно делается и автоматическое управление памятью и выстраивание иерархии объектов и работа с событиями и менеджеры размещения объектов и многе другое. Короче смотрите на архитектуру Qt, там всё прекрасно реализовано и всё прекрасно работает, а порог вхождения там вполне адекватный. Выше конечно чем во всяких PyQT или PyGTK, но вполне можно научится без особых мозговых усилий за приемлемое время.

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

Например, мусоросборка и GUI. Большая тема. Мне, например, есть что сказать по этому поводу.
Здесь же получается каша из холивара и обобщённых мнений, и у меня нет желания писать сюда в комментарии какой-либо серьёзный материал.
Может быть дело в том, что в нем, в отличие, например от Java нет встроенных визуальных компонентов и их надо придумывать ручками ил пользоваться билдером/кьютом/другими имярек?
Вам оставили выбор. Вы можете даже сборщик мусора сделать если уж так хочется
Давайте не будем путать умные указатели с подсчетом ссылок со сборкой мусора -это совсем разные вещи.
Перейди хотя бы по первой ссылке, это STL, она должна быть во всех реализациях C++. Сборка мусора — garbage collection, и часть этой системы умные указатели. В вики описаны основные принципы.

ru.wikipedia.org/wiki/Сборка_мусора

Если говорить в целом, то сборка мусора это управление памятью (memory) и автоматическое удаление объектов, когда их больше нельзя использовать, а значит и незачем держать в памяти. На C++ предоставляется выбор, или ручное управление памятью, или использование стандартных, сторонних и самописных реализаций.

Ссылки между прочим часто считают для того, чтобы удалить объект, когда их количество становится равно нулю. Давайте всё же не будем судить о C++ на основе других языков и реализаций стандартных библиотек, дескать те истинные сборщики мусора, а вот это что-то не то хотя бы потому что оно на C++, а не на ххх.
можно конечно расписать по каждому пункту, например «Нет синтаксических средств переключения событий» я вообще не понял — автор, что, удивляется тому, что надо вручную вызвать родительскую реализацию repaint'а? И какое это имеет отношение к «переключению событий»? Что он вообще подразумевает под переключением?
В общем, такое ощущение, что оригинальный текст писал какой-то школьник.

Имхо, хорошим опровержением статье в целом является сам факт наличия такой библиотеки, как Qt.
посмотрел на дату оригинального текста, 95-й год, вопросы снимаются, тогда на С++ действительно не умели писать…
тогда как-то глупо было вобще перевод статьи этой выкладывать )
Хотя почему такая статья понятно, в то время нормальных тулкитов не было. C# тоже еще не появился, а Java только только делает первые шаги. Единственным средсвом был С/C++.
Действительно — okmij.org/ftp/cpp-digest/CPP-GUI-mismatch.html

Ну тогда и обсуждать нечего.

ISO/IEC 14882:1998 C++
ISO/IEC 14882:2003 C++

По мне так нет смысла опускаться ниже 1998 года. Это не обязательно школьник писал, просто человек из далёкого прошлого, когда мир был другим и знаний было накоплено меньше.
>Имхо, хорошим опровержением статье в целом является сам факт наличия такой библиотеки, как Qt.

угу. С костылём под названием MOC
Sign up to leave a comment.

Articles