Кого мы хотим подготовить, обучая студентов программированию на C++? Что они должны вынести из курса? Мне кажется, важно научить писать программы. Красивые, эффективные, сопровождаемые. Язык – лишь инструмент программирования. И надо научиться пользоваться инструментом. Вот когда в автошколе учат вождению машину, совсем не обязательно знать тонкости устройства шины CAN, обеспечивающей связь всех устройств автомобиля. Да, надо узнать, что такое тормоза, руль, двигатель, но на каких-то деталях надо остановиться, и, самое, главное, надо научиться пользоваться автомобилем (то есть водить автомобиль) безопасно, уверенно и т.п.
А почему мы заставляем студентов знать подробности языка, которые нельзя продемонстрировать на разумном примере? Например, множественное наследование (я уже молчу о виртуальном наследование в сочетании с множественном). Для этого нужны примеры, большие примеры, огромное количество понятий (например, интерфейсы), чтобы студент почувствовал, что и зачем. А мы с упорством сумасшедших рассказываем о том, какие члены классов будут видны или не видны в той или иной ситуации.
Вот объясните мне, кто-нибудь использовал перегрузку наряду с виртуальностью?
class A
{
public:
virtual int f();
};
class B : public A
{
public:
virtual int f(double);
};
Что это нормально, это работает? Зачем нужны эти знания? А кто перегружал функции, расположенные в разных областях видимости?
class A
{
void f(char);
public:
void f(int);
};
A a;
a.f('a');
Ну кто такое делает в реальных задачах? Зачем студентов заставлять разбирать эти примеры?
Как я понял из интервью Бьерна Страуструпа, это проблема преподавания Computer Science не только на факультете ВМиК МГУ. Он говорит, кого мы готовим? lanugage lawyers? По-моему, это очень точно английское словосочетание… Мы готовим студентов стать членами комитета ISO по стандартизации C++?
Они еще не поняли до конца, зачем нужны конструкторы, как написать надежные классы, они не узнают в рамках курса ничего про юнит-тесты, например, зато приведенные выше примеры будут щелкать как орешки.
Кому это нужно? Самоудовлетворение от задалбливания в умы студентов бесполезных знаний?
Почему мы не экзаменуем их на умение программировать? Ну или хотя бы на знание базовых конструкций языка? Зачем такие извращенные примеры? Если бы я опубликовал весь вариант работы, которую писали студенты, думаю, многие были бы в шоке. Я уверяю, что подавляющее большинство потрясающих, талантливых C++-программистов не смогут решить этот вариант на «пять». Но от этого они не становятся хуже, а претензии надо предъявлять тем, кто составил такую программу курса, предъявляет такие требования к студентам. Как они могут полюбить такой предмет?
По-моему, пора остановиться и сменить ориентиры.
Я поздравляю вас с 1 апреля! Почему именно вас – можно узнать в моём блоге.
Андрей, я полностью с Вами согласен. Знание лексем абсолютно не подразумевает понимания процесса. К сожалению, для бизнеса зачастую нужно имено зание языка, а за то, чтобы это знание потекло в нужное русло отвечает некое конторское светило. Хотя я бы дорого отдал за человека, на которого можно свалить задачу целиком и лишь изредка корректировать и помогать, а не дергаться на каждый его вопрос с периодом 10-15 минут.
К сожалению, это общая проблема, которая не только касается Си++, но и любого другое практического курса, который читается у нас на факультете в форме лекций. Обратите внимание, как время будет, на курс «сети». Уверен – будет смех сквозь слёзы.
С уважением, Юрий (Студент 3 Курса факультета ВМиК)
Я всеми этим вопросами много задавался. У нас в Новосибирске при компании Parallels есть спец-курс по плюсам. Может Вам будет интересно взглянуть: http://parallels.nsu.ru/WackoWiki/SpeckursCxx
Спасибо, было интересно. К сожалению, из-за недостатка времени, я уже не преподаю. Но это был замечательный опыт!
Это типичная проблема «академизма и практики». Такие намеренно усложнённые и запутанные примеры полезны с академической точки зрения, ибо они позволяют усвоить тонкости базового языка (а возможно, и его стандартной библиотеки). Однако, как верно написал Андрей, в реальных программных проектах так никто не делает. Скажу больше: если в реальных проектах кто-то так делает, то ему нужно бить по рукам, причём сильно. С другой стороны, я не совсем согласен с Андреем в его высказывании «о множественном наследовании в сочетании с виртуальным». Такого рода иерархии иногда весьма полезны, особенно при разработке библиотек широкого применения. Поэтому знать, скажем, о порядке вызова конструкторов в подобных иерархиях весьма полезно. Тем более в этом нет ничего архисложного, нужно просто один раз изучить и попробовать.
Оба приведенные Вами примеры полностью вытекают из задач программирования и является следствеем многоочередного стиля программирования. 1 вариант – это банальное переопределение метода (хоть и виртуального). Это чисто Страуструпа решение, хуже того если мы просто ошибемся и напишем полностью идентичный метод но с константностью, то в этом случае тоже самое получим, что и приведенный пример. 2 вариант – это перегрузка и совершенно правильно компилятор не хочет компилировать такой код, очень часто программисты меняют область видимости и в этом случае тогда менялся бы логика поведения программы, что неправильно.
Большой, речь идет об обучении на бумаге, без компилятора. Держать в памяти правила, соответствующий таким редким случаям, кажется мне неразумным. Пост об этом. После нескольких лет работы с языком все это откладывается, но при обучении длиной в семестр это – не самое главное.