Группа SE (Кринкин М) — различия между версиями
Krinkin.m (обсуждение | вклад) (→Ссылки) |
Krinkin.m (обсуждение | вклад) |
||
(не показаны 3 промежуточные версии этого же участника) | |||
Строка 1: | Строка 1: | ||
== Ссылки == | == Ссылки == | ||
− | [https://docs.google.com/spreadsheet/ccc?key=0Av5GItXuPPyddElWTGhJVjZiNVhFYjkzYk9YTlJab0E&usp=sharing рейтинг] | + | [https://docs.google.com/spreadsheet/ccc?key=0Av5GItXuPPyddHNWLWoyWEpoX3RnX1otQVozU25ycWc&usp=sharing рейтинг весна] |
+ | |||
+ | [https://docs.google.com/spreadsheet/ccc?key=0Av5GItXuPPyddElWTGhJVjZiNVhFYjkzYk9YTlJab0E&usp=sharing рейтинг осень] | ||
[https://github.com/cplusplus/draft стандарт на github] | [https://github.com/cplusplus/draft стандарт на github] | ||
Строка 28: | Строка 30: | ||
или просто: | или просто: | ||
− | valgrind ./a.out | + | valgrind ./a.out |
+ | |||
+ | === Использование cppcheck === | ||
+ | |||
+ | В самом простом случае использование cppcheck выглядит так: | ||
+ | |||
+ | cppcheck --enable=all . | ||
+ | |||
+ | в этом случае cppcheck найдет все cpp файлы в текущем каталоге и проверит их, можно указать конкретный файл: | ||
+ | |||
+ | cppcheck --enable=all test.cpp | ||
== Задания == | == Задания == | ||
Строка 67: | Строка 79: | ||
}; | }; | ||
#endif /*__FILE_H__*/ | #endif /*__FILE_H__*/ | ||
+ | |||
+ | |||
+ | === Unqiue Ptr === | ||
+ | |||
+ | Требуется написать умный указатель, который обеспечивает автоматическое освобождение ресурсов. В шаблоне должны быть переопределены операторы =, -> и *, методы T * release() и void reset(T *). Использовать 11 стандарт запрещено. Кроме описанных ранее операторов, шаблон должен поддерживать следующие варианты использования: | ||
+ | |||
+ | unqiue_ptr<int> new_int() { return new int(10); } | ||
+ | unique_ptr<int, array_deleter<int> > new_int_array() { return unqiue_ptr<int, array_deleter<int> >(new int[10]); } | ||
+ | unqiue_ptr<int, void(*)(void *)> malloc_int() { return unqiue_ptr<int, void(*)(void *)>((int *)malloc(sizeof(int)), &free); } | ||
+ | int main() | ||
+ | { | ||
+ | unique_ptr<int> v1 = new_int(); | ||
+ | unique_ptr<int, array_deleter<int> > v2 = new_int_array(); | ||
+ | unique_ptr<int, void(*)(void *)> v3 = malloc_int(); | ||
+ | v1.reset(NULL); //освобождает память | ||
+ | std::cout << *v3 << std::endl; // печатает int | ||
+ | return 0; | ||
+ | } | ||
+ | |||
+ | === Боль и страдания === | ||
+ | |||
+ | #include <iostream> | ||
+ | #include <type_traits> | ||
+ | #include <string> | ||
+ | namespace detail | ||
+ | { | ||
+ | template <typename T> | ||
+ | T min_impl(T&& arg) | ||
+ | { | ||
+ | return std::forward<T>(arg); | ||
+ | } | ||
+ | template <typename T1, typename T2> | ||
+ | typename std::common_type<T1, T2>::type min_impl(T1&& t1, T2&& t2) | ||
+ | { | ||
+ | return (t1 < t2) ? t1 : t2; | ||
+ | } | ||
+ | template <typename T, typename ... Other> | ||
+ | typename std::common_type<T, Other...>::type min_impl(T&& t, Other&& ... other) | ||
+ | { | ||
+ | return min_impl(std::forward<T>(t), min_impl(std::forward<Other>(other)...)); | ||
+ | } | ||
+ | } | ||
+ | template <typename ... Args> | ||
+ | typename std::common_type<Args...>::type min(Args&& ... args) | ||
+ | { | ||
+ | return detail::min_impl(std::forward<Args>(args)...); | ||
+ | } | ||
+ | int main() | ||
+ | { | ||
+ | char const *ptr1 = "10"; | ||
+ | char const *ptr2 = "20"; | ||
+ | std::cout << min(ptr2, ptr1, std::string("30")) << std::endl; | ||
+ | return 0; | ||
+ | } |
Текущая версия на 17:09, 10 апреля 2014
Содержание
Ссылки
человеческая документация по C++
простенький статический анализатор кода
Полезности
Полезные флаги компилятора (g++/clang++)
- -Wall - повышает уровень проверок компилятора, при этом компилятор выдает большое число предупреждений
- -Werror - все предупреждения будут интерпретироваться компилятором как ошибки
- -pedantic - проверка кода на соответствие стандарту (какому именно зависит от флага -std)
- -Weffc++ - проверка некоторых рекомендаций из книги (ничего не делает clang++)
Поиск утечек памяти с помощью Valgrind
Пусть a.out имя бинарного файла программы в текущем каталоге, тогда чтобы проверить использование памяти запускаем ее следующим образом:
valgrind --tool=memcheck ./a.out
или просто:
valgrind ./a.out
Использование cppcheck
В самом простом случае использование cppcheck выглядит так:
cppcheck --enable=all .
в этом случае cppcheck найдет все cpp файлы в текущем каталоге и проверит их, можно указать конкретный файл:
cppcheck --enable=all test.cpp
Задания
Обертка над FILE
Требуется используя cstdio написать класс/структуру file. file должен позволять узнать статус потока ввода/вывода (ошибка, конец файла и т. д.), а также содержать набор методов для ввода/вывода строк и чисел. Так как копирование для такого класса операция не осмысленная (почему?), нужно запретить копирование объекта класса. Сигнатуры методов остаются на ваше усмотрение, для примера, это может выглядеть так (советую немного подумать и не повторять):
#ifndef __FILE_H__ #define __FILE_H__ #include <string> class file { public: enum open_mode { Read, Write }; file(); explicit file(std::string const &fname, open_mode mode = Read); ~file(); void open(std::string const &fname, open_mode mode = Read); void close(); open_mode mode() const; bool opened() const; bool eof() const; bool error() const; size_t write(char const *buf, size_t size); size_t write(std::string const &str); size_t write(char value); size_t write(long value); size_t write(unsigned long value); size_t write(double value); size_t newline(); size_t read(char *buf, size_t size); size_t read(std::string &word); size_t read(char &c); size_t read(long &value); size_t read(unsigned long &value); size_t read(double &value); size_t readline(std::string &line); }; #endif /*__FILE_H__*/
Unqiue Ptr
Требуется написать умный указатель, который обеспечивает автоматическое освобождение ресурсов. В шаблоне должны быть переопределены операторы =, -> и *, методы T * release() и void reset(T *). Использовать 11 стандарт запрещено. Кроме описанных ранее операторов, шаблон должен поддерживать следующие варианты использования:
unqiue_ptr<int> new_int() { return new int(10); } unique_ptr<int, array_deleter<int> > new_int_array() { return unqiue_ptr<int, array_deleter<int> >(new int[10]); } unqiue_ptr<int, void(*)(void *)> malloc_int() { return unqiue_ptr<int, void(*)(void *)>((int *)malloc(sizeof(int)), &free); } int main() { unique_ptr<int> v1 = new_int(); unique_ptr<int, array_deleter<int> > v2 = new_int_array(); unique_ptr<int, void(*)(void *)> v3 = malloc_int(); v1.reset(NULL); //освобождает память std::cout << *v3 << std::endl; // печатает int return 0; }
Боль и страдания
#include <iostream> #include <type_traits> #include <string> namespace detail { template <typename T> T min_impl(T&& arg) { return std::forward<T>(arg); } template <typename T1, typename T2> typename std::common_type<T1, T2>::type min_impl(T1&& t1, T2&& t2) { return (t1 < t2) ? t1 : t2; } template <typename T, typename ... Other> typename std::common_type<T, Other...>::type min_impl(T&& t, Other&& ... other) { return min_impl(std::forward<T>(t), min_impl(std::forward<Other>(other)...)); } } template <typename ... Args> typename std::common_type<Args...>::type min(Args&& ... args) { return detail::min_impl(std::forward<Args>(args)...); } int main() { char const *ptr1 = "10"; char const *ptr2 = "20"; std::cout << min(ptr2, ptr1, std::string("30")) << std::endl; return 0; }