Я постараюсь оставлять на этой странице заметки к лекциям (неотвеченные вопросы, спорные моменты, просто замечания и пр.) пока их не забыл.
12 Дек 2006
Обещенная литература
Еще про std::vector
Забыл упомянуть о способе борьбы с неожиданными перераспределениями памяти в std::vector. Есть метод std::vector::reserve который позвляет зарезервировать необходимое количество памяти заранее, например если известно примерное число элементов, которые будут храниться в векторе:
std::vector v;
v.reserve(10000);
v.push_back(1);
v.size(); // == 1
v.capacity(); // >= 10000
Метод std::vector::capacity позволяет понять сколько элементов можно положить в вектор без перераспределения памяти.
Об использовании алгоритмов
На самом деле, использование STL (и им подобных) алгоритмов кажется через чур запутанным или, возможно неуместным, не всем новичкам в C++. Тут все дело в менталитете — для тех кто переходит на C++ с C, Pascal или Java обобщенное программирование может показаться трюком «для гуру» который только нарушает читаемость программ. Для тех же, кто имеет опыт в
функциональных языках типа LISP или Scheme, или, хотя бы, Python или Ruby, возможности обобщенного программирования в C++ могут показаться весьма скудными.
См. также Замыкания
31 Окт 2006
NVI Idiom и «стандартная» практика программирования
Мне был задан вопрос: откуда свалилась это правило использовать невиртуальные функции в интерфейсе класса, а виртуальные только в закрытых и защищенных секциях и что, например в Java, давно существует подход определенно другой. Я про Java много что наговорил, кроме главного. Главное в том, что независимо от того насколько плох или хорош Java или C++, имея много общего, во многом они различаются по стилю программирования (т.е. идиоматически). Во многих случаях нельзя прямо руководствоваться своим опытом программирования на Java в C++ (и наоброт) и это должно быть очевидно: в Java нет деструкторов, есть сборка мусора и все классы автоматически наследуют Object. Это и многое другое вносит существенные коррективы.
Поэтому существуют, скажем ОО паттерны (общие для многих ОО языков программирования) и идиомы, специфичные к одному.
Что касается NVI – то это скорее идиома, однако существует родственный паттерн — Template Method, который успешно применяется в Java.
См. также: Herb Sutter. Virtuality. C/C++ Users Journal, 19(9), September 2001.
10 Окт 2006
О качестве программ
Было несколько вопросов и реплик относительно безопасности программ, безопасности языков программирования и т.п. Я бы хотел высказать свое мнение на свежую голову, при этом никоим образом не пытаюсь навязать его как авторитетное.
Итак,
- Качественное ПО – это то ПО, которое удовлетворяет поставленным требованиям. И в конечном итоге удовлетворяет пользователя.
- Надежное ПО – это программы, которые мало подвержены к отказам. Т.е. программа ведет себя предсказуемо и валидно (согласно требованиям) даже в случаях, когда переданы неверные данные на вход, нехватает ресурсов и т.п.
- Есть также понятие времени наработки на отказ, у надежного ПО оно должно быть достаточно (или очень) велико.
- Под безопасным кодом я подразумеваю прежде всего код, продуктом которого является надежное ПО.
Все это я написал не заглядывая в словари, спец литературу и т.п., поэтому прошу меня исправить, если что.
Теперь о безопасности языков программирования. Далее приводится цитата из книги <<Дизайн и эволюция языка C + +>> (раздел 14.2.4), которая мне кажется кое что может прояснить:
Хорошие программы – это продукт хорошего образования, удачного проектирования, адекватного тестирования и т.д., а не наличие в языке средств, которые предположительно должны использоваться только «правильно». Употребить во вред можно любое средство, поэтому вопрос не в том, можно ли чем-то воспользоваться неправильно (можно!) или будут ли этим неправильно пользоваться (будут!). Вопрос в том, необходимо ли данное средство при условии его правильного употребления настолько, чтобы оправдать затраты на его реализацию, удастся ли смоделировать его с помощью других средств языка и реально ли с помощью обучения обратить во благо неправильное использование.
3 Окт 2006
Вопрос про строковый литерал
Вопрос: Что является константным в выражении
const char str[] = String literal; массив или char?
Ответ: Конечно char.
Вот текст из Страуструпа:
The type of a string literal is array of the appropriate number of cons characters, so Bohr is of type
const char [5].
A string literal can be assigned to a char*. This is allowed because in previous definitions of C and C + +, the type of a string literal was char*. Allowing the assignment of a string literal to a char* ensures that millions of lines of C and C++ remain valid.
Вопрос про ошибку компиляции (личный)
Сев в автобус, я вдруг понял, что совершенно зря пообещал побить костылем одного господина. Дело в том, что вопрос был совершенно законным. Дело в порядке поиска имен. Компилятор ищет функцию, которую следует вызвать в каждом конкретном случае, среди доступных областей видимости в определенном порядке. Область видимости имен класса является одним из первых кандидатов для поиска. Когда компилятор находит функцию (или несколько) с соответствующим именем (независимо от параметров), поиск прекращается.
В конкретном случае, класс, по всей видимости, содержал функцию f(int*) с искомым именем, но другими параметрами. Не найдя других кандидатов внутри класса, компилятор остановил поиск и сообщил об ошибке.