Перейти к основному содержимому

5.06. ООП

Разработчику Архитектору

ООП

C++ полностью поддерживает ООП: инкапсуляция, наследование, полиморфизм, абстракция.

Объявление класса:

class Person {
private:
string name;

public:
Person(string n) : name(n) {}

void greet() const {
cout << "Hello, my name is " << name << endl;
}
};

Создание экземпляра:

Person p("Alice");
p.greet();

Наследование:

class Student : public Person {
public:
Student(string n) : Person(n) {}
};

Инкапсуляция:

Доступ к членам класса контролируется модификаторами:

  • private
  • protected
  • public

Полиморфизм:

Поддерживается через виртуальные функции и переопределение:

class Animal {
public:
virtual void speak() { cout << "Animal sound" << endl; }
};

class Dog : public Animal {
public:
void speak() override { cout << "Woof!" << endl; }
};

Конструкторы / деструкторы:

class MyClass {
public:
MyClass() { cout << "Constructor" << endl; }
~MyClass() { cout << "Destructor" << endl; }
};

Перегрузка функций и операторов:

int add(int a, int b) { return a + b; }
double add(double a, double b) { return a + b; }

// Перегрузка оператора
class Point {
public:
int x, y;
Point operator+(const Point& other) {
return Point{x + other.x, y + other.y};
}
};

Управление памятью:

Ручное управление через new / delete

Поддержка умных указателей (unique_ptr, shared_ptr) начиная с C++11

unique_ptr<int> p(new int(5));

Шаблоны (Templates):

Поддерживают обобщённое программирование.

template<typename T>
T max(T a, T b) {
return (a > b) ? a : b;
}

cout << max(3, 5); // вызов с int
cout << max(3.5, 2.1); // вызов с double

STL (Standard Template Library):

Мощная библиотека, содержащая контейнеры, алгоритмы и итераторы.

Примеры:

  • vector<T> — динамический массив
  • map<K,V> — отображение
  • set<T> — множество

list<T> — двусвязный список

#include <vector>
vector<int> v = {1, 2, 3};
v.push_back(4);

Исключения:

Поддержка исключений через try / catch / throw.

try {
throw runtime_error("Error occurred!");
} catch (const exception& e) {
cerr << e.what() << endl;
}

Namespaces:

Организация кода в пространства имён.

namespace math {
int add(int a, int b) { return a + b; }
}

cout << math::add(2, 3);

Move семантика и Rvalue-ссылки (C++11+):

Увеличивает производительность при передаче/возврате больших объектов.

string createString() {
string temp = "Hello";
return temp; // move вместо копирования
}

Lambda-выражения (C++11+):

Анонимные функции.

auto sum = [](int a, int b) { return a + b; };
cout << sum(2, 3);

Smart Pointers (C++11+):

  • unique_ptr — владение одним указателем
  • shared_ptr — совместное владение
  • weak_ptr — неувеличивает счетчик ссылок

C++ — один из самых мощных и гибких языков программирования. Он используется в разработке игр, системном ПО, высоконагруженных серверах, embedded-системах и многом другом. Хотя он сложнее по сравнению с языками вроде Python или Kotlin, он предоставляет максимальный контроль над производительностью и ресурсами.

Давайте рассмотрим его особенности

  1. Управление памятью.

В Java и C# есть сборщик мусора (GC) – не нужно думать о выделении и освобождении памяти. Объекты создаются в куче через new, но освобождаются автоматически.

В C++ нет сборщика мусора. Память управляется вручную. Объекты можно создавать локально (на стеке) и динамически (на куче):

Person p;                    // Локальный объект (стек)
Person* p = new Person(); // Объект на куче
delete p; // Нужно вручную удалить

В C++ программист отвечает за память, это сложно, но позволяет писать более быстрый и компактный код.

  1. Указатели и ссылки.

В Java нет указателей, только ссылки на объекты, которые нельзя арифметически изменять. В C++ есть указатели (*) и ссылки (&). Можно работать с адресами памяти, изменять значения напрямую.

int x = 10;
int* ptr = &x; // указатель на x
*ptr = 20; // меняем значение через указатель

int& ref = x; // ссылка на x
ref = 30; // тоже меняется x

C++ даёт прямой доступ к памяти, но и ответственность за ошибки тоже на программисте.

  1. Структуры и классы.

В Java только классы, struct отсутствует, все объекты – ссылочные типы.

В C++ есть class, и struct. Разница в уровне доступа по умолчанию, class - приватные члены по умолчанию, struct – публичные.

struct Point {
int x, y; // public по умолчанию
};

class Circle {
int radius; // private по умолчанию
public:
void setRadius(int r) { radius = r; }
};

В C++ struct и class – почти одно и то же, но struct часто используется для данных без логики.

  1. Перегрузка операторов.

В Java операторы нельзя перегружать. Исключение + для строк.

В C++ полная свобода – можно переопределять операторы.

Point operator+(const Point& a, const Point& b) {
return Point{a.x + b.x, a.y + b.y};
}

C++ поддерживает операторную перегрузку, что делает математические классы удобными.

  1. Шаблоны (Templates) и Generics.

В Java и C# Generics реализуются через типы-заполнители, но тип стирается во время выполнения.

List<int> list = new List<int>();

В C++ шаблоны – это метапрограммирование: шаблон компилируется для каждого типа отдельно.

template <typename T>
T max(T a, T b) {
return (a > b) ? a : b;
}

int i = max(3, 5); // инстанцирование для int
float f = max(3.1f, 5.6f); // инстанцирование для float

В C++ шаблоны – это часть компиляции, а не выполнения. Они мощнее, но сложнее в отладке.

  1. Конструкторы и деструкторы.

В Java есть конструкторы, есть финализатор finalize(), но его вызов не гарантирован.

public class MyClass {
public MyClass() { ... }
}

В C++ есть деструкторы, которые вызываются при выходе из области видимости:

class FileHandler {
public:
FileHandler(const char* name) { /* открываем файл */ }
~FileHandler() { /* закрываем файл */ }
};

{
FileHandler file("data.txt"); // при выходе из блока вызывается ~FileHandler()
}

Отличие в том, что в C++ есть RAII (Resource Acquisition Is Initialization) – управление ресурсами через деструкторы.

  1. Модификаторы доступа и уровни видимости.

В Java есть модификаторы: private, protected, public, package-private.

В C++ то же самое, но уровень доступа задаётся для групп членов класса:

class MyClass {
private:
int secret;
public:
void doSomething();
protected:
float internalData;
};

В C++ уровень доступа задаётся до члена класса, а не рядом с каждым.

  1. SLT (Standard Template Library).

C++ предоставляет мощную стандартную библиотеку, аналогичную Collections в Java или коллекциям в C#.

JavaC#C++
ArrayList<T>List<T>std::vector<T>
HashMap<K,V>Dictionary<K,V>std::map<K,V>
HashSet<T>HashSet<T>std::unordered_set<T>
Queue<T>Queue<T>std::queue<T>

SLT – шаблонная библиотека, очень гибка и эффективная, но требует понимания итераторов.

  1. Поддержка многопоточности.
ЯзыкПоддержка потоков
JavaThread, Runnable, ExecutorService
C#Task, async/await, Thread
C++std::thread, std::mutex, std::future

Пример:

#include <thread>
void threadFunc() {
std::cout << "Hello from thread";
}

int main() {
std::thread t(threadFunc);
t.join();
return 0;
}

В C++ нет встроенной поддержки async/await. Но можно использовать std::future, std::promise.

C++ это низкоуровневый, производительный и гибкий язык, который:

  • даёт контроль над памятью и процессором;
  • подходит для системного программирования, игр, embedded-систем;
  • требует больше внимания к деталям, чем Java или C#.

Если мы знаем Java и C#, то работа с циклами, условиями, классами нам будет понятна, однако придётся научиться управлять памятью, понимать указатели, научиться работать с STL.