Группа SE (Кринкин М) — различия между версиями

Материал из SEWiki
Перейти к: навигация, поиск
(Полезности)
 
(не показаны 2 промежуточные версии этого же участника)
Строка 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]
Строка 77: Строка 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

Ссылки

рейтинг весна

рейтинг осень

стандарт на github

человеческая документация по C++

сайт Valgrind

простенький статический анализатор кода

Полезности

Полезные флаги компилятора (g++/clang++)

  1. -Wall - повышает уровень проверок компилятора, при этом компилятор выдает большое число предупреждений
  2. -Werror - все предупреждения будут интерпретироваться компилятором как ошибки
  3. -pedantic - проверка кода на соответствие стандарту (какому именно зависит от флага -std)
  4. -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;
   }