{"action":"created","comment":{"url":"https://api.github.com/repos/adambard/learnxinyminutes-docs/pulls/comments/55902947","id":55902947,"diff_hunk":"@@ -0,0 +1,893 @@\n+---\n+language: c++\n+filename: learncpp-ru.cpp\n+contributors:\n+    - [\"Steven Basart\", \"http://github.com/xksteven\"]\n+    - [\"Matt Kline\", \"https://github.com/mrkline\"]\n+    - [\"Geoff Liu\", \"http://geoffliu.me\"]\n+    - [\"Connor Waters\", \"http://github.com/connorwaters\"]\n+translators:\n+    - [\"Bohdan Shtepan\", \"http://modern-dev.com\"]\n+lang: ru-ru\n+---\n+\n+C++ - компилируемый, статически типизированный язык программирования общего назначения, который,\n+[как заявляет создатель языка Бьёрн Страуструп](http://channel9.msdn.com/Events/Lang-NEXT/Lang-NEXT-2014/Keynote),\n+был разработан как\n+\n+- \"лучшая замена C\"\n+- язык с поддержкой абстракции данных\n+- язык с поддержкой объектно-ориентированого программирования\n+- язык с поддержкой обобщенного программирования\n+\n+Хотя его синтаксис может показаться более трудным или сложным для понимания, чем в более современных языках,\n+он широко применяется т.к. код написанный на C++ компилируется в набор инструкций, которые могут быть выполнены напрямую\n+процессором. C++ широко используется для разработки программного обеспечения, являясь одним из самых популярных языков\n+программирования. Область его применения включает создание операционных систем, разнообразных прикладных программ, драйверов\n+устройств, приложений для встраиваемых систем, высокопроизводительных серверов, а также развлекательных приложений (игр).\n+\n+```c++\n+//////////////////\n+// Сравнение с C\n+//////////////////\n+\n+// C++ практически представляет собой надмножество C и имеет схожий синтаксис\n+// для объявления переменных, примитивов и функций.\n+\n+// Также как и в С, точкой входа в программу является функция с именем main,\n+// которая возвращает целочисленное значение.\n+// Это значение является кодом ответа программы.\n+// Смотрите https://goo.gl/JYGKyv для более подробной информации.\n+int main(int argc, char** argv)\n+{\n+    // Аргументы командной строки переданные в программу хранятся в переменных\n+\t// argc и argv, также как и в C.\n+    // argc указывает на количество аргументов,\n+    // а argv является масивом C-подобных строк (char*), который непосредсвенно\n+\t// содержит аргументы.\n+    // Первым аргументом всегда передается имя программы.\n+    // argc и argv могут быть опущены если вы не планируете работать с аругментамы\n+\t// коммандной строки.\n+\t// Тогда сигнатура функции будет иметь следующий вид int main()\n+\n+    // Возвращаемое значение 0 указывает на успешное завершение программы.\n+    return 0;\n+}\n+\n+// Тем не менее, C++ имеет свои отличия:\n+\n+// В C++, символьные литералы являются символами.\n+sizeof('c') == sizeof(char) == 1\n+\n+// В С, символьные литералы - целые числа.\n+sizeof('c') == sizeof(int)\n+\n+\n+// C++ имеет строго прототипирование.\n+void func(); // функция, которая не принимает аргументов.\n+\n+// In C\n+void func(); // функция, которая может принять сколько угодно аргументов.\n+\n+// Использование nullptr вместо NULL в C++.\n+int* ip = nullptr;\n+\n+// Стандартные заголовочные файлы С доступны в С++,\n+// но с префиксом \"с\" и не имеют суффикса .h.\n+#include <cstdio>\n+\n+int main()\n+{\n+    printf(\"Hello, world!\\n\");\n+    return 0;\n+}\n+\n+///////////////////////\n+// Перегрузка функций\n+///////////////////////\n+\n+// С++ поддерживает перегрузку функций, при условии,\n+// что каждая функция принимает различные параметры.\n+\n+void print(char const* myString)\n+{\n+    printf(\"String %s\\n\", myString);\n+}\n+\n+void print(int myInt)\n+{\n+    printf(\"My int is %d\", myInt);\n+}\n+\n+int main()\n+{\n+    print(\"Hello\"); // Использование void print(const char*)\n+    print(15); // Использование void print(int)\n+}\n+\n+/////////////////////////////\n+// Аргументы функций по умолчанию\n+/////////////////////////////\n+\n+// Вы можете предоставить аргументы по умолчанию для функции,\n+// если они не предоставлены при вызове функции.\n+\n+void doSomethingWithInts(int a = 1, int b = 4)\n+{\n+    // Здесь что-то делаем с числами\n+}\n+\n+int main()\n+{\n+    doSomethingWithInts();      // a = 1,  b = 4\n+    doSomethingWithInts(20);    // a = 20, b = 4\n+    doSomethingWithInts(20, 5); // a = 20, b = 5\n+}\n+\n+// Аргументы по умолчанию должен быть в конце списка аргументов.\n+\n+void invalidDeclaration(int a = 1, int b) // Ошибка!\n+{\n+}\n+\n+\n+/////////////\n+// Пространства имен\n+/////////////\n+\n+// Пространства имен предоставляют отдельные области для переменной,\n+// функции и других объявлений.\n+// Пространства имен могут быть вложенными.\n+\n+namespace First {\n+    namespace Nested {\n+        void foo()\n+        {\n+            printf(\"This is First::Nested::foo\\n\");\n+        }\n+    } // конец пространства имен Nested\n+} // конец пространства имен First\n+\n+namespace Second {\n+    void foo()\n+    {\n+        printf(\"This is Second::foo\\n\")\n+    }\n+}\n+\n+void foo()\n+{\n+    printf(\"This is global foo\\n\");\n+}\n+\n+int main()\n+{\n+    // Включает все функци с пространства имен Second в текущую область видимости.\n+    // Обратите внимание, что простой вызов foo() больше не работает,\n+    // так как теперь не ясно вызываем ли мы foo с пространства имен Second или\n+\t// из глобальной области видимости.\n+    using namespace Second;\n+\n+    Second::foo(); // напечатает \"This is Second::foo\"\n+    First::Nested::foo(); // напечатает \"This is First::Nested::foo\"\n+    ::foo(); // напечатает \"This is global foo\"\n+}\n+\n+///////////////\n+// Ввод/Вывод\n+///////////////\n+\n+// Вводи и вывод в C++ использует потоки\n+// cin, cout и cerr предоставлнеы методами stdin, stdout и stderr.\n+// << - оператор вставки, >> - оператор извлечения.\n+\n+#include <iostream> // Включение файла для работы с потоками Ввода\\Вывода.\n+\n+using namespace std; // Потоки доступны в пространстве имен std (стандартная библиотека)\n+\n+int main()\n+{\n+   int myInt;\n+\n+   // Выводит stdout (или терминал\\экран)\n+   cout << \"Enter your favorite number:\\n\";\n+   // Принимает ввод\n+   cin >> myInt;\n+\n+   // cout может принимать форматирование\n+   cout << \"Your favorite number is \" << myInt << \"\\n\";\n+   // напечатает \"Your favorite number is <myInt>\"\n+\n+    cerr << \"Used for error messages\";\n+}\n+\n+//////////\n+// Строки\n+//////////\n+\n+// Строки в C++ являются объектами и имеют много функций-членов.\n+#include <string>\n+\n+using namespace std; // Строки также доступны в пространстве имен std (стандартная библиотек)\n+\n+string myString = \"Hello\";\n+string myOtherString = \" World\";\n+\n+// + используется для конкатенации строк.\n+cout << myString + myOtherString; // \"Hello World\"\n+\n+cout << myString + \" You\"; // \"Hello You\"\n+\n+// Строки в C++ могут изменяться и имеют семантику значений.\n+myString.append(\" Dog\");\n+cout << myString; // \"Hello Dog\"\n+\n+\n+/////////////\n+// Ссылки\n+/////////////\n+\n+// В добавок к указателям доступных в C,\n+// C++ имеет _ссылки_.\n+// Это такой тип указателя, который не может быть переназначен после инициализации\n+// и не может иметь значения null.\n+// Ссылки имеют схожий с переменными синтаксис:\n+// * больше не используется для разыменования и\n+// & (адрес) не используется для назначения.\n+\n+using namespace std;\n+\n+string foo = \"I am foo\";\n+string bar = \"I am bar\";\n+\n+\n+string& fooRef = foo; // Здесь создается указатель на foo.\n+fooRef += \". Hi!\"; // Изменяет foo по ссылке\n+cout << fooRef; // Печатает \"I am foo. Hi!\"\n+\n+// Не переназначает \"fooRef\". Это тоже самое как \"foo = bar\", и\n+//   foo == \"I am bar\"\n+// после этой строчки.\n+cout << &fooRef << endl; // Печатает адрес foo\n+fooRef = bar;\n+cout << &fooRef << endl; // По-прежнему печатает адрес foo\n+cout << fooRef;  // Печатает \"I am bar\"\n+\n+// Адрес fooRef остается тем же, то есть он по-прежнему ссылается на foo.\n+\n+\n+const string& barRef = bar; // Создает const со ссылкой на bar.\n+// Также как и C, значения const (и указателей и ссылок) не могут быть изменены.\n+barRef += \". Hi!\"; // Ошибка, указатель const не может быть изменен.\n+\n+// Обходной путь: Прежде чем мы рассмотрим указатели более детально, нам нужно ознакомится\n+// с концепцией известной как \"временный объект\". Представьте, что мы имеем следующий код\n+string tempObjectFun() { ... }\n+string retVal = tempObjectFun();\n+\n+// Вот что на самом деле происходит во второй строе:\n+//   - tempObjectFun возвращает строковый объект\n+//   - с возвращаемого объекта создается новая строка в качестве аргумента конструктору\n+//   - возвращаемый объект уничтожается\n+// Возвращаемый объект называется временным объектом. Временные объекты создаются\n+// когда функция возвращает объект, и уничтожаются в конце выполнения обрамляющего\n+// выражения (По крайней мере, так это описывает спецификация, хотя компиляторы могут\n+// изменять это поведение. Для более подробной информации смотрите \"оптимизация\n+// возвращаемого значения\". Таким образом в этом коде:\n+foo(bar(tempObjectFun()))\n+\n+// предполагая, что foo и bar существуют, объект возвращаемый tempObjectFun передается\n+// в bar, и уничтожается перед вызовом foo.\n+\n+// Возвращаемся к указателям. Исключением для правила \"в конце выполнения обрамляющего\n+// выражения\" является временный объект привязанный к ссылке const, в этом случае\n+// его жизненный цикл продлевается до текущей области видимости:\n+\n+void constReferenceTempObjectFun() {\n+  // constRef получает временный объект, и он действителен до конца этой функции.\n+  const string& constRef = tempObjectFun();\n+  ...\n+}\n+\n+// В C++11 предоставлен еще один тип ссылок специально для временных объектов.\n+// objects. Вы не можете объявить переменную этого типа, но он имеет приоритет в\n+// в резолюции перегрузки:\n+\n+void someFun(string& s) { ... }  // Обычная ссылка\n+void someFun(string&& s) { ... }  // Ссылка на временный объект\n+\n+string foo;\n+someFun(foo);  // Выполняет версию с обычной ссылкой\n+someFun(tempObjectFun());  // Выполняет версию с временной ссылкой.\n+\n+// Например, существуют следующие две версии конструктора std::basic_string:\n+basic_string(const basic_string& other);\n+basic_string(basic_string&& other);\n+\n+// Идея в том, если мы конструируем новую строку из временного объекта (который \n+// так или иначе будет уничтожен), мы можем использовать более эффективный конструктор,\n+// который \"спасает\" части этой временной строки. Эта концепция была названа\n+// \"move semantics\".\n+\n+/////////////////////\n+// Перечисления\n+/////////////////////\n+\n+// Перечисления - способ объявления констант и установки их значений в основном\n+// использующийся для упрощения чтения кода.\n+enum ECarTypes\n+{\n+  Sedan,\n+  Hatchback,\n+  SUV,\n+  Wagon\n+};\n+\n+ECarTypes GetPreferredCarType()\n+{\n+\treturn ECarTypes::Hatchback;\n+}\n+\n+// На момент выхода C++11 есть простой способ назначения типа перечисления, что\n+// полезно в случае сериализации данных и преобразований между конечным типом и \n+// соответствующими константами.\n+enum ECarTypes : uint8_t\n+{\n+  Sedan, // 0\n+  Hatchback, // 1\n+  SUV = 254, // 254\n+  Hybrid // 255\n+};\n+\n+void WriteByteToFile(uint8_t InputValue)\n+{\n+\t// Сериализуем InputValue в файл\n+}\n+\n+void WritePreferredCarTypeToFile(ECarTypes InputCarType)\n+{\n+\t// Перечисление неявно преобразуется в uint8_t из-за раннее объявленного\n+\t// типа перечисления.\n+\tWriteByteToFile(InputCarType);\n+}\n+\n+// С другой стороны, чтобы избежать случайного приведения к целочисленному типу или\n+// другому перечислению, вы можете создать класс перечисления, который не будет\n+// преобразовываться неявно.\n+enum class ECarTypes : uint8_t\n+{\n+  Sedan, // 0\n+  Hatchback, // 1\n+  SUV = 254, // 254\n+  Hybrid // 255\n+};\n+\n+void WriteByteToFile(uint8_t InputValue)\n+{\n+\t// Сериализуем InputValue в файл\n+}\n+\n+void WritePreferredCarTypeToFile(ECarTypes InputCarType)\n+{\n+\t// Хотя ECarTypes имеет тип uint8_t, код не будет скомпилирован из-за того,\n+\t// что перечисление было объявлено как класс перечисления.\n+\tWriteByteToFile(InputCarType);\n+}\n+\n+//////////////////////////////////////////\n+// Классы и объектно-ориентированное программирование\n+//////////////////////////////////////////\n+\n+// Пример классов\n+#include <iostream>\n+\n+// Объявление класса.\n+// Обычно классы объявляют в заголовочном (.h или .hpp) файле.\n+class Dog {\n+    // Переменный-члены и функции являются частными по умолчанию.\n+    std::string name;\n+    int weight;\n+\n+// Все члены после этой сроки являются открытыми\n+// пока \"private:\" или \"protected:\" не будет объявлено.\n+public:\n+\n+    // Конструктор по умолчанию\n+    Dog();\n+\n+    // Объявление функций-членов\n+    // Обратите внимание, мы используем std::string здесь вместо использования\n+    // using namespace std;\n+    // выше.\n+    // Никогда не размещайте выражение \"using namespace\" в заголовке.\n+    void setName(const std::string& dogsName);\n+\n+    void setWeight(int dogsWeight);\n+\n+    // Функции, которые не изменяют состояние объекта,\n+    // должны быть помечены как const.\n+    // Это позволяет вызывать их если дана const ссылка на объект.\n+    // Обратите внимание, функции должны быть явно объявлены как _virtual_\n+    // если вы хотите перегрузить их в производных классах.\n+    // Функции не являются виртуальными по умолчания для повышения производительности.\n+    virtual void print() const;\n+\n+    // Такде функции могут быть определены внутри тела класса.\n+    // Функции, определенные следующим образом, автоматически встроены.\n+    void bark() const { std::cout << name << \" barks!\\n\"; }\n+\n+    // Наряду с конструкторами, в C++ есть деструкторы.\n+    // Они вызываются, когда объект удаляется или выпадает с области видимости.\n+    // Это активирует мощную парадигму программирования известную как RAII\n+    // (смотрите ниже)\n+    // Деструктор должен быть виртуальным, если класс будет производным.\n+    // Если он не виртуальный, тогда деструктор производного класса не будет вызван\n+    // если объект удален по ссылке или указателю базового класса.\n+    // or pointer.\n+    virtual ~Dog();\n+\n+}; // Определение класса должно завершатся точкой с запятой.\n+\n+// Функции-члены класса, как правило, реализуются в .cpp файлах.\n+Dog::Dog()\n+{\n+    std::cout << \"A dog has been constructed\\n\";\n+}\n+\n+// Объекты (такие как строки) должны передаваться по ссылке если вы будете\n+// изменять их, или const-ссылке если нет.\n+void Dog::setName(const std::string& dogsName)\n+{\n+    name = dogsName;\n+}\n+\n+void Dog::setWeight(int dogsWeight)\n+{\n+    weight = dogsWeight;\n+}\n+\n+// Обратите внимание, \"virtual\" требуется только в объявлении, не в определении.\n+void Dog::print() const\n+{\n+    std::cout << \"Dog is \" << name << \" and weighs \" << weight << \"kg\\n\";\n+}\n+\n+Dog::~Dog()\n+{\n+    cout << \"Goodbye \" << name << \"\\n\";\n+}\n+\n+int main() {\n+    Dog myDog; // Печатает \"A dog has been constructed\"\n+    myDog.setName(\"Barkley\");\n+    myDog.setWeight(10);\n+    myDog.print(); // Печатает \"Dog is Barkley and weighs 10 kg\"\n+    return 0;\n+} // Печатает \"Goodbye Barkley\"\n+\n+// Интерфейсы:\n+\n+// Этот класс наследует все открытые и защищенные члены класса Dog\n+// также как и все закрытые, но не может непосредственно получить доступ к закрытым\n+// членам\\методам без открытых или защищенных методов для этого.\n+class OwnedDog : public Dog {\n+\n+    void setOwner(const std::string& dogsOwner);\n+\n+    // Переопределяем поведение функции печати для всех OwnedDog. Смотрите\n+    // https://goo.gl/3kuH2x для боле общего введения, если вы не знакомы\n+    // с концепцией полиморфизма подтипов (включения).\n+    // Ключевое слово override является необязательным, но указывает что метод\n+    // на самом деле перегружается в базовом классе.\n+    void print() const override;\n+\n+private:\n+    std::string owner;\n+};\n+\n+// Тем временем, в соответствующем .cpp файле:\n+\n+void OwnedDog::setOwner(const std::string& dogsOwner)\n+{\n+    owner = dogsOwner;\n+}\n+\n+void OwnedDog::print() const\n+{\n+    Dog::print(); // Вызывает функцию print в базовом классе Dog\n+    std::cout << \"Dog is owned by \" << owner << \"\\n\";\n+    // Печатает \"Dog is <name> and weights <weight>\"\n+    //        \"Dog is owned by <owner>\"\n+}\n+\n+//////////////////////////////////////////\n+// Инициализация и перегрузка операторов.\n+//////////////////////////////////////////\n+\n+// В C++ вы можете перегрузить поведение таких операторов: +, -, *, / и др..\n+// Это делается путем определения функции, которая вызывается,\n+// когда используется оператор.\n+\n+#include <iostream>\n+using namespace std;\n+\n+class Point {\n+public:\n+    // Значения по умолчанию для переменных-членов могут быть установлены\n+\t// следующим образом.\n+    double x = 0;\n+    double y = 0;\n+\n+    // Определяем новый конструктор, который инициализирует Point со значениями\n+    // по умолчанию (0, 0)\n+    Point() { };\n+\n+    // Следующий синтаксис известен как список инициализации и является верным способом \n+\t// инициализировать значения членов класса.\n+    Point (double a, double b) :\n+        x(a),\n+        y(b)\n+    { /* Ничего не делайте кроме инициализации значений */ }\n+\n+    // Перегружаем оперот +.\n+    Point operator+(const Point& rhs) const;\n+\n+    // Перегружаем оператор +=.\n+    Point& operator+=(const Point& rhs);\n+\n+    // Имеет смысл добавить перегрузку операторов - и -=,\n+    // но для краткости мы опустим эти детали.\n+};\n+\n+Point Point::operator+(const Point& rhs) const\n+{\n+    // Создает новую точку, которая является суммой этой точки и rhs.\n+    return Point(x + rhs.x, y + rhs.y);\n+}\n+\n+Point& Point::operator+=(const Point& rhs)\n+{\n+    x += rhs.x;\n+    y += rhs.y;\n+    return *this;\n+}\n+\n+int main () {\n+    Point up (0,1);\n+    Point right (1,0);\n+    // Здесь происходит вызов оператора + класса Point\n+    // Точка \"up\" вызывает + (функция) с параметром \"right\"\n+    Point result = up + right;\n+    // Печатает \"Result is upright (1,1)\"\n+    cout << \"Result is upright (\" << result.x << ',' << result.y << \")\\n\";\n+    return 0;\n+}\n+\n+/////////////////////\n+// Шаблоны\n+/////////////////////\n+\n+// Шаблоны в С++, в основном, используются для обобщенного программирования, хотя\n+// они гораздо более мощны чем дженерики в других языках. Они также поддерживают\n+// явные, частные и функциональные типы классов; на самом деле, они являются\n+// тьюринг-полным языком встроенным в C++!\n+\n+// Мы начнем с наиболее распространенного типа обобщенного программирования. Чтобы\n+// определить класс или функцию, которая принимает параметр типа:\n+template<class T>\n+class Box {\n+public:\n+    // В этом классе T может быть любого типа.\n+    void insert(const T&) { ... }\n+};\n+\n+// Во время компиляции, компилятор фактически генерирует копии каждого шаблона\n+// с замещенными параметрами, по-этому полное определение класса должно присутствовать\n+// при каждом вызове. Именно по-этому классы шаблонов полностью определены в\n+// заголовочных файлах.\n+\n+// Чтобы создать экземпляр класса шаблона на стеке:\n+Box<int> intBox;\n+\n+// и вы можете использовать его, как и ожидалось:\n+intBox.insert(123);\n+\n+// Вы, конечно, можете использовать вложенные шаблоны:\n+Box<Box<int> > boxOfBox;\n+boxOfBox.insert(intBox);\n+\n+// Вплоть до С++11, вы должны были ставить пробел между двумя символами '>', иначе '>>'\n+// принимался парсером, как оператор правого сдвига.\n+\n+// Иногда вы можете увидеть\n+//   template<typename T>\n+// вместо этого. В этом случае, ключевые слова 'class' и 'typename' _в основном_\n+// взаимозаменяемыми. Для более подробной информации смотрите\n+//   http://en.wikipedia.org/wiki/Typename\n+// (да-да, это ключевое слово имеет собственную страничку на вики).\n+\n+// Аналогичным образом, шаблонная функция:\n+template<class T>\n+void barkThreeTimes(const T& input)\n+{\n+    input.bark();\n+    input.bark();\n+    input.bark();\n+}\n+\n+// Обратите внимание, что здесь ничего не указано о типе параметра. Компилятор\n+// будет генерировать и затем проверять тип каждый вызов шаблона, по-этому\n+// данная функция работает с любым типом 'T', который имеет метод 'bark'.\n+\n+Dog fluffy;\n+fluffy.setName(\"Fluffy\")\n+barkThreeTimes(fluffy); // Печатает \"Fluffy barks\" три раза.\n+\n+//Параметры шаблона не должны быть классами:\n+template<int Y>\n+void printMessage() {\n+  cout << \"Learn C++ in \" << Y << \" minutes!\" << endl;\n+}\n+\n+// В конце концов, вы можете явно специализировать шаблоны для более эффективного\n+// кода. Конечно, большинство реальных случаев использования специализации\n+// не так тривиально, как это. Обратите внимание, вам все еще нужно явно объявить\n+// функцию (или класс) в качестве шаблона, даже если вы явно указали все параметры.\n+template<>\n+void printMessage<10>() {\n+  cout << \"Learn C++ faster in only 10 minutes!\" << endl;\n+}\n+\n+printMessage<20>();  // Печатает \"Learn C++ in 20 minutes!\"\n+printMessage<10>();  // Печатает \"Learn C++ faster in only 10 minutes!\"\n+\n+\n+/////////////////////\n+// Обработка исключений\n+/////////////////////\n+\n+// Стандартная библиотека предоставляет несколько типов исключений\n+// (смотрите http://en.cppreference.com/w/cpp/error/exception)\n+// но, в принципе, любой тип может быть брошен в качестве исключения.\n+#include <exception>\n+#include <stdexcept>\n+\n+// Все исключения брошены внутри блока _try_ могут быть пойманы в последующем блоке\n+// _catch_.\n+try {\n+    // Не выделяйте память в куче для исключений с помощью ключевого слова _new_.\n+    throw std::runtime_error(\"A problem occurred\");\n+}\n+\n+// Поймайте исключение по константной ссылке, если они являются объектами\n+catch (const std::exception& ex)\n+{\n+    std::cout << ex.what();\n+}\n+\n+// Ловит любое исключение не пойманное предыдущим блоком _catch_\n+catch (...)\n+{\n+    std::cout << \"Unknown exception caught\";\n+    throw; // Повторный выброс исключения\n+}\n+\n+///////\n+// Получение ресурса есть инициализация (RAII)\n+///////\n+\n+// Программная идиома объектно-ориентированного программирования, смысл которой\n+// заключается в том, что с помощью тех или иных программных механизмов получение\n+// некоторого ресурса неразрывно совмещается с инициализацией, а освобождение -\n+// с уничтожением объекта.\n+\n+// Чтобы понять на сколько это полезно,\n+// рассмотрим функцию, которая использует обработчик файлов в С:\n+void doSomethingWithAFile(const char* filename)\n+{\n+    // Для начала, предположим, ничего не может потерпеть неудачу.\n+\n+    FILE* fh = fopen(filename, \"r\"); // Открываем файл в режиме чтения.\n+\n+    doSomethingWithTheFile(fh);\n+    doSomethingElseWithIt(fh);\n+\n+    fclose(fh); // Закрываем обработчик файла.\n+}\n+\n+// К сожалению, вещи быстро осложняется обработкой ошибок.\n+// Предположим fopen может потерпеть неудачу, тогда doSomethingWithTheFile и\n+// doSomethingElseWithIt вернут коды ошибок если потерпят неудачу.\n+//  (Исключения являются предпочтительным способом обработки ошибок,\n+//   но некоторые программисты, особенно те, кто имеет большой опыт работы с С,\n+//   не согласны с аргументами о полезности исключений).\n+// Теперь мы должны проверить каждый вызов на наличие ошибок и закрыть обработчик\n+// файла если таковы есть.\n+bool doSomethingWithAFile(const char* filename)\n+{\n+    FILE* fh = fopen(filename, \"r\"); // Открывает файл в режиме чтения\n+    if (fh == nullptr) // В случае неудачи возвращаемый указатель принимает null.\n+        return false; // Сообщает об неудаче вызывающему.\n+\n+    // Предположим, каждая функция возвращает false в случае неудачи\n+    if (!doSomethingWithTheFile(fh)) {\n+        fclose(fh); // Закрываем обработчик файл чтобы не было утечек\n+        return false; // Сообщает об ошибке.\n+    }\n+    if (!doSomethingElseWithIt(fh)) {\n+        fclose(fh); // Закрываем обработчик файл чтобы не было утечек\n+        return false; // Сообщает об ошибке.\n+    }\n+\n+    fclose(fh); // Закрываем обработчик файл чтобы не было утечек\n+    return true; // Указывает на успех\n+}\n+\n+// C-программисты часто упорядочивают это с помощью goto:\n+bool doSomethingWithAFile(const char* filename)\n+{\n+    FILE* fh = fopen(filename, \"r\");\n+    if (fh == nullptr)\n+        return false;\n+\n+    if (!doSomethingWithTheFile(fh))\n+        goto failure;\n+\n+    if (!doSomethingElseWithIt(fh))\n+        goto failure;\n+\n+    fclose(fh); // Close the file","path":"ru-ru/c++-ru.html.markdown","position":739,"original_position":739,"commit_id":"aad2d2b6f2e44f7647d0512dea263029c1d4d1fa","original_commit_id":"aad2d2b6f2e44f7647d0512dea263029c1d4d1fa","user":{"login":"Oire","id":595597,"avatar_url":"https://avatars.githubusercontent.com/u/595597?v=3","gravatar_id":"","url":"https://api.github.com/users/Oire","html_url":"https://github.com/Oire","followers_url":"https://api.github.com/users/Oire/followers","following_url":"https://api.github.com/users/Oire/following{/other_user}","gists_url":"https://api.github.com/users/Oire/gists{/gist_id}","starred_url":"https://api.github.com/users/Oire/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/Oire/subscriptions","organizations_url":"https://api.github.com/users/Oire/orgs","repos_url":"https://api.github.com/users/Oire/repos","events_url":"https://api.github.com/users/Oire/events{/privacy}","received_events_url":"https://api.github.com/users/Oire/received_events","type":"User","site_admin":false},"body":"Закрываем файл?","created_at":"2016-03-11T23:09:00Z","updated_at":"2016-03-11T23:09:00Z","html_url":"https://github.com/adambard/learnxinyminutes-docs/pull/2050#discussion_r55902947","pull_request_url":"https://api.github.com/repos/adambard/learnxinyminutes-docs/pulls/2050","_links":{"self":{"href":"https://api.github.com/repos/adambard/learnxinyminutes-docs/pulls/comments/55902947"},"html":{"href":"https://github.com/adambard/learnxinyminutes-docs/pull/2050#discussion_r55902947"},"pull_request":{"href":"https://api.github.com/repos/adambard/learnxinyminutes-docs/pulls/2050"}}},"pull_request":{"url":"https://api.github.com/repos/adambard/learnxinyminutes-docs/pulls/2050","id":52755705,"html_url":"https://github.com/adambard/learnxinyminutes-docs/pull/2050","diff_url":"https://github.com/adambard/learnxinyminutes-docs/pull/2050.diff","patch_url":"https://github.com/adambard/learnxinyminutes-docs/pull/2050.patch","issue_url":"https://api.github.com/repos/adambard/learnxinyminutes-docs/issues/2050","number":2050,"state":"open","locked":false,"title":"[c++/ru]","user":{"login":"virtyaluk","id":795984,"avatar_url":"https://avatars.githubusercontent.com/u/795984?v=3","gravatar_id":"","url":"https://api.github.com/users/virtyaluk","html_url":"https://github.com/virtyaluk","followers_url":"https://api.github.com/users/virtyaluk/followers","following_url":"https://api.github.com/users/virtyaluk/following{/other_user}","gists_url":"https://api.github.com/users/virtyaluk/gists{/gist_id}","starred_url":"https://api.github.com/users/virtyaluk/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/virtyaluk/subscriptions","organizations_url":"https://api.github.com/users/virtyaluk/orgs","repos_url":"https://api.github.com/users/virtyaluk/repos","events_url":"https://api.github.com/users/virtyaluk/events{/privacy}","received_events_url":"https://api.github.com/users/virtyaluk/received_events","type":"User","site_admin":false},"body":"Made russian translation of C++ guide https://github.com/adambard/learnxinyminutes-docs/issues/2046","created_at":"2015-12-05T14:14:39Z","updated_at":"2016-03-11T23:09:00Z","closed_at":null,"merged_at":null,"merge_commit_sha":"523cb16b19a72c98a87aebcbffc39729659ee087","assignee":{"login":"Oire","id":595597,"avatar_url":"https://avatars.githubusercontent.com/u/595597?v=3","gravatar_id":"","url":"https://api.github.com/users/Oire","html_url":"https://github.com/Oire","followers_url":"https://api.github.com/users/Oire/followers","following_url":"https://api.github.com/users/Oire/following{/other_user}","gists_url":"https://api.github.com/users/Oire/gists{/gist_id}","starred_url":"https://api.github.com/users/Oire/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/Oire/subscriptions","organizations_url":"https://api.github.com/users/Oire/orgs","repos_url":"https://api.github.com/users/Oire/repos","events_url":"https://api.github.com/users/Oire/events{/privacy}","received_events_url":"https://api.github.com/users/Oire/received_events","type":"User","site_admin":false},"milestone":null,"commits_url":"https://api.github.com/repos/adambard/learnxinyminutes-docs/pulls/2050/commits","review_comments_url":"https://api.github.com/repos/adambard/learnxinyminutes-docs/pulls/2050/comments","review_comment_url":"https://api.github.com/repos/adambard/learnxinyminutes-docs/pulls/comments{/number}","comments_url":"https://api.github.com/repos/adambard/learnxinyminutes-docs/issues/2050/comments","statuses_url":"https://api.github.com/repos/adambard/learnxinyminutes-docs/statuses/aad2d2b6f2e44f7647d0512dea263029c1d4d1fa","head":{"label":"virtyaluk:master","ref":"master","sha":"aad2d2b6f2e44f7647d0512dea263029c1d4d1fa","user":{"login":"virtyaluk","id":795984,"avatar_url":"https://avatars.githubusercontent.com/u/795984?v=3","gravatar_id":"","url":"https://api.github.com/users/virtyaluk","html_url":"https://github.com/virtyaluk","followers_url":"https://api.github.com/users/virtyaluk/followers","following_url":"https://api.github.com/users/virtyaluk/following{/other_user}","gists_url":"https://api.github.com/users/virtyaluk/gists{/gist_id}","starred_url":"https://api.github.com/users/virtyaluk/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/virtyaluk/subscriptions","organizations_url":"https://api.github.com/users/virtyaluk/orgs","repos_url":"https://api.github.com/users/virtyaluk/repos","events_url":"https://api.github.com/users/virtyaluk/events{/privacy}","received_events_url":"https://api.github.com/users/virtyaluk/received_events","type":"User","site_admin":false},"repo":{"id":47277047,"name":"learnxinyminutes-docs","full_name":"virtyaluk/learnxinyminutes-docs","owner":{"login":"virtyaluk","id":795984,"avatar_url":"https://avatars.githubusercontent.com/u/795984?v=3","gravatar_id":"","url":"https://api.github.com/users/virtyaluk","html_url":"https://github.com/virtyaluk","followers_url":"https://api.github.com/users/virtyaluk/followers","following_url":"https://api.github.com/users/virtyaluk/following{/other_user}","gists_url":"https://api.github.com/users/virtyaluk/gists{/gist_id}","starred_url":"https://api.github.com/users/virtyaluk/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/virtyaluk/subscriptions","organizations_url":"https://api.github.com/users/virtyaluk/orgs","repos_url":"https://api.github.com/users/virtyaluk/repos","events_url":"https://api.github.com/users/virtyaluk/events{/privacy}","received_events_url":"https://api.github.com/users/virtyaluk/received_events","type":"User","site_admin":false},"private":false,"html_url":"https://github.com/virtyaluk/learnxinyminutes-docs","description":"Code documentation written as code! How novel and totally my idea!","fork":true,"url":"https://api.github.com/repos/virtyaluk/learnxinyminutes-docs","forks_url":"https://api.github.com/repos/virtyaluk/learnxinyminutes-docs/forks","keys_url":"https://api.github.com/repos/virtyaluk/learnxinyminutes-docs/keys{/key_id}","collaborators_url":"https://api.github.com/repos/virtyaluk/learnxinyminutes-docs/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/virtyaluk/learnxinyminutes-docs/teams","hooks_url":"https://api.github.com/repos/virtyaluk/learnxinyminutes-docs/hooks","issue_events_url":"https://api.github.com/repos/virtyaluk/learnxinyminutes-docs/issues/events{/number}","events_url":"https://api.github.com/repos/virtyaluk/learnxinyminutes-docs/events","assignees_url":"https://api.github.com/repos/virtyaluk/learnxinyminutes-docs/assignees{/user}","branches_url":"https://api.github.com/repos/virtyaluk/learnxinyminutes-docs/branches{/branch}","tags_url":"https://api.github.com/repos/virtyaluk/learnxinyminutes-docs/tags","blobs_url":"https://api.github.com/repos/virtyaluk/learnxinyminutes-docs/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/virtyaluk/learnxinyminutes-docs/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/virtyaluk/learnxinyminutes-docs/git/refs{/sha}","trees_url":"https://api.github.com/repos/virtyaluk/learnxinyminutes-docs/git/trees{/sha}","statuses_url":"https://api.github.com/repos/virtyaluk/learnxinyminutes-docs/statuses/{sha}","languages_url":"https://api.github.com/repos/virtyaluk/learnxinyminutes-docs/languages","stargazers_url":"https://api.github.com/repos/virtyaluk/learnxinyminutes-docs/stargazers","contributors_url":"https://api.github.com/repos/virtyaluk/learnxinyminutes-docs/contributors","subscribers_url":"https://api.github.com/repos/virtyaluk/learnxinyminutes-docs/subscribers","subscription_url":"https://api.github.com/repos/virtyaluk/learnxinyminutes-docs/subscription","commits_url":"https://api.github.com/repos/virtyaluk/learnxinyminutes-docs/commits{/sha}","git_commits_url":"https://api.github.com/repos/virtyaluk/learnxinyminutes-docs/git/commits{/sha}","comments_url":"https://api.github.com/repos/virtyaluk/learnxinyminutes-docs/comments{/number}","issue_comment_url":"https://api.github.com/repos/virtyaluk/learnxinyminutes-docs/issues/comments{/number}","contents_url":"https://api.github.com/repos/virtyaluk/learnxinyminutes-docs/contents/{+path}","compare_url":"https://api.github.com/repos/virtyaluk/learnxinyminutes-docs/compare/{base}...{head}","merges_url":"https://api.github.com/repos/virtyaluk/learnxinyminutes-docs/merges","archive_url":"https://api.github.com/repos/virtyaluk/learnxinyminutes-docs/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/virtyaluk/learnxinyminutes-docs/downloads","issues_url":"https://api.github.com/repos/virtyaluk/learnxinyminutes-docs/issues{/number}","pulls_url":"https://api.github.com/repos/virtyaluk/learnxinyminutes-docs/pulls{/number}","milestones_url":"https://api.github.com/repos/virtyaluk/learnxinyminutes-docs/milestones{/number}","notifications_url":"https://api.github.com/repos/virtyaluk/learnxinyminutes-docs/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/virtyaluk/learnxinyminutes-docs/labels{/name}","releases_url":"https://api.github.com/repos/virtyaluk/learnxinyminutes-docs/releases{/id}","deployments_url":"https://api.github.com/repos/virtyaluk/learnxinyminutes-docs/deployments","created_at":"2015-12-02T17:31:58Z","updated_at":"2015-12-02T17:32:01Z","pushed_at":"2015-12-05T14:07:41Z","git_url":"git://github.com/virtyaluk/learnxinyminutes-docs.git","ssh_url":"git@github.com:virtyaluk/learnxinyminutes-docs.git","clone_url":"https://github.com/virtyaluk/learnxinyminutes-docs.git","svn_url":"https://github.com/virtyaluk/learnxinyminutes-docs","homepage":"http://learnxinyminutes.com/","size":8307,"stargazers_count":0,"watchers_count":0,"language":"TeX","has_issues":false,"has_downloads":true,"has_wiki":true,"has_pages":false,"forks_count":1,"mirror_url":null,"open_issues_count":0,"forks":1,"open_issues":0,"watchers":0,"default_branch":"master"}},"base":{"label":"adambard:master","ref":"master","sha":"69acce34c15c540bedf3dc040649d3c9abd3c52b","user":{"login":"adambard","id":515720,"avatar_url":"https://avatars.githubusercontent.com/u/515720?v=3","gravatar_id":"","url":"https://api.github.com/users/adambard","html_url":"https://github.com/adambard","followers_url":"https://api.github.com/users/adambard/followers","following_url":"https://api.github.com/users/adambard/following{/other_user}","gists_url":"https://api.github.com/users/adambard/gists{/gist_id}","starred_url":"https://api.github.com/users/adambard/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/adambard/subscriptions","organizations_url":"https://api.github.com/users/adambard/orgs","repos_url":"https://api.github.com/users/adambard/repos","events_url":"https://api.github.com/users/adambard/events{/privacy}","received_events_url":"https://api.github.com/users/adambard/received_events","type":"User","site_admin":false},"repo":{"id":10974951,"name":"learnxinyminutes-docs","full_name":"adambard/learnxinyminutes-docs","owner":{"login":"adambard","id":515720,"avatar_url":"https://avatars.githubusercontent.com/u/515720?v=3","gravatar_id":"","url":"https://api.github.com/users/adambard","html_url":"https://github.com/adambard","followers_url":"https://api.github.com/users/adambard/followers","following_url":"https://api.github.com/users/adambard/following{/other_user}","gists_url":"https://api.github.com/users/adambard/gists{/gist_id}","starred_url":"https://api.github.com/users/adambard/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/adambard/subscriptions","organizations_url":"https://api.github.com/users/adambard/orgs","repos_url":"https://api.github.com/users/adambard/repos","events_url":"https://api.github.com/users/adambard/events{/privacy}","received_events_url":"https://api.github.com/users/adambard/received_events","type":"User","site_admin":false},"private":false,"html_url":"https://github.com/adambard/learnxinyminutes-docs","description":"Code documentation written as code! How novel and totally my idea!","fork":false,"url":"https://api.github.com/repos/adambard/learnxinyminutes-docs","forks_url":"https://api.github.com/repos/adambard/learnxinyminutes-docs/forks","keys_url":"https://api.github.com/repos/adambard/learnxinyminutes-docs/keys{/key_id}","collaborators_url":"https://api.github.com/repos/adambard/learnxinyminutes-docs/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/adambard/learnxinyminutes-docs/teams","hooks_url":"https://api.github.com/repos/adambard/learnxinyminutes-docs/hooks","issue_events_url":"https://api.github.com/repos/adambard/learnxinyminutes-docs/issues/events{/number}","events_url":"https://api.github.com/repos/adambard/learnxinyminutes-docs/events","assignees_url":"https://api.github.com/repos/adambard/learnxinyminutes-docs/assignees{/user}","branches_url":"https://api.github.com/repos/adambard/learnxinyminutes-docs/branches{/branch}","tags_url":"https://api.github.com/repos/adambard/learnxinyminutes-docs/tags","blobs_url":"https://api.github.com/repos/adambard/learnxinyminutes-docs/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/adambard/learnxinyminutes-docs/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/adambard/learnxinyminutes-docs/git/refs{/sha}","trees_url":"https://api.github.com/repos/adambard/learnxinyminutes-docs/git/trees{/sha}","statuses_url":"https://api.github.com/repos/adambard/learnxinyminutes-docs/statuses/{sha}","languages_url":"https://api.github.com/repos/adambard/learnxinyminutes-docs/languages","stargazers_url":"https://api.github.com/repos/adambard/learnxinyminutes-docs/stargazers","contributors_url":"https://api.github.com/repos/adambard/learnxinyminutes-docs/contributors","subscribers_url":"https://api.github.com/repos/adambard/learnxinyminutes-docs/subscribers","subscription_url":"https://api.github.com/repos/adambard/learnxinyminutes-docs/subscription","commits_url":"https://api.github.com/repos/adambard/learnxinyminutes-docs/commits{/sha}","git_commits_url":"https://api.github.com/repos/adambard/learnxinyminutes-docs/git/commits{/sha}","comments_url":"https://api.github.com/repos/adambard/learnxinyminutes-docs/comments{/number}","issue_comment_url":"https://api.github.com/repos/adambard/learnxinyminutes-docs/issues/comments{/number}","contents_url":"https://api.github.com/repos/adambard/learnxinyminutes-docs/contents/{+path}","compare_url":"https://api.github.com/repos/adambard/learnxinyminutes-docs/compare/{base}...{head}","merges_url":"https://api.github.com/repos/adambard/learnxinyminutes-docs/merges","archive_url":"https://api.github.com/repos/adambard/learnxinyminutes-docs/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/adambard/learnxinyminutes-docs/downloads","issues_url":"https://api.github.com/repos/adambard/learnxinyminutes-docs/issues{/number}","pulls_url":"https://api.github.com/repos/adambard/learnxinyminutes-docs/pulls{/number}","milestones_url":"https://api.github.com/repos/adambard/learnxinyminutes-docs/milestones{/number}","notifications_url":"https://api.github.com/repos/adambard/learnxinyminutes-docs/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/adambard/learnxinyminutes-docs/labels{/name}","releases_url":"https://api.github.com/repos/adambard/learnxinyminutes-docs/releases{/id}","deployments_url":"https://api.github.com/repos/adambard/learnxinyminutes-docs/deployments","created_at":"2013-06-26T17:58:34Z","updated_at":"2016-03-11T16:44:04Z","pushed_at":"2016-03-11T19:05:15Z","git_url":"git://github.com/adambard/learnxinyminutes-docs.git","ssh_url":"git@github.com:adambard/learnxinyminutes-docs.git","clone_url":"https://github.com/adambard/learnxinyminutes-docs.git","svn_url":"https://github.com/adambard/learnxinyminutes-docs","homepage":"http://learnxinyminutes.com/","size":12697,"stargazers_count":3392,"watchers_count":3392,"language":"TeX","has_issues":true,"has_downloads":true,"has_wiki":true,"has_pages":false,"forks_count":1364,"mirror_url":null,"open_issues_count":304,"forks":1364,"open_issues":304,"watchers":3392,"default_branch":"master"}},"_links":{"self":{"href":"https://api.github.com/repos/adambard/learnxinyminutes-docs/pulls/2050"},"html":{"href":"https://github.com/adambard/learnxinyminutes-docs/pull/2050"},"issue":{"href":"https://api.github.com/repos/adambard/learnxinyminutes-docs/issues/2050"},"comments":{"href":"https://api.github.com/repos/adambard/learnxinyminutes-docs/issues/2050/comments"},"review_comments":{"href":"https://api.github.com/repos/adambard/learnxinyminutes-docs/pulls/2050/comments"},"review_comment":{"href":"https://api.github.com/repos/adambard/learnxinyminutes-docs/pulls/comments{/number}"},"commits":{"href":"https://api.github.com/repos/adambard/learnxinyminutes-docs/pulls/2050/commits"},"statuses":{"href":"https://api.github.com/repos/adambard/learnxinyminutes-docs/statuses/aad2d2b6f2e44f7647d0512dea263029c1d4d1fa"}}}}