<MyRusakov.ru />

Создание нейросетей на Python

Создание нейросетей на Python

Этот курс научит Вас созданию нейросетей на Python. Курс рассчитан на начинающих. Вся информация идёт от простого к сложному очень маленькими шажками. При этом глубокое знание математики не требуется. Поскольку в курсе Вы будете получать эти знания по мере необходимости.

Из курса Вы узнаете всю необходимую теорию и терминологию. Научитесь создавать нейросети самых разных архитектур и обучать их. Также Вы создадите собственный фреймворк. Что очень важно проделать для грамотного использования того же PyTorch. Затем Вы изучите и сам PyTorch.

Помимо уроков к курсу идут упражнения для закрепления материала.

Ещё Вы получите Бонусы, дополняющие основной курс: "Распознавание изображений", "Анализ настроения по тексту отзыва", "Программирование на Python с Нуля до Гуру".

Подробнее
Подписка

Подпишитесь на мой канал на YouTube, где я регулярно публикую новые видео.

YouTube Подписаться

Подписавшись по E-mail, Вы будете получать уведомления о новых статьях.

Подписка Подписаться

Добавляйтесь ко мне в друзья ВКонтакте! Отзывы о сайте и обо мне оставляйте в моей группе.

Мой аккаунт Мой аккаунт Моя группа
Опрос

Какая тема Вас интересует больше?

Конструкторы в C++: как правильно создавать объекты и инициализировать поля

Конструкторы в C++: как правильно создавать объекты и инициализировать поля

Поисковый запрос, под который написана эта статья: конструктор в C++. Если вы уже знаете, что такое класс, но не до конца понимаете, как правильно создавать объекты, эта тема одна из самых важных в основах C++.

Что такое конструктор в C++

Конструктор — это специальная функция-член класса, которая вызывается автоматически при создании объекта. У конструктора такое же имя, как у класса, и у него нет возвращаемого типа, даже void.

#include <iostream>
#include <string>

class User {
public:
    std::string name;
    int age;

    User() {
        name = "Гость";
        age = 0;
    }
};

int main() {
    User user;
    std::cout << user.name << ", << user.age << std::endl;
}

Здесь User() — конструктор по умолчанию. Он сработает в момент выполнения строки User user;.

Конструктор по умолчанию

Конструктор по умолчанию — это конструктор, который можно вызвать без аргументов. Он нужен, когда объект должен иметь базовые значения.

class Point {
public:
    int x;
    int y;

    Point() {
        x = 0;
        y = 0;
    }
};

Такой подход понятен, но в современном C++ часто лучше инициализировать поля сразу при объявлении:

class Point {
public:
    int x = 0;
    int y = 0;
};

Если специальная логика не нужна, это короче и безопаснее.

Конструктор с параметрами

Чаще объект нужно создать уже с конкретными данными. Для этого используются конструкторы с параметрами.

class Product {
public:
    std::string title;
    double price;

    Product(const std::string& productTitle, double productPrice) {
        title = productTitle;
        price = productPrice;
    }
};

int main() {
    Product book("C++ для начинающих", 1200.0);
    std::cout << book.title << ": " << book.price << std::endl;
}

Теперь объект нельзя случайно оставить без названия и цены, если вы создаёте его через этот конструктор.

Список инициализации: правильный способ задавать поля

В C++ есть важный синтаксис — список инициализации членов класса. Он записывается после параметров конструктора через двоеточие.

class Product {
private:
    std::string title;
    double price;

public:
    Product(const std::string& productTitle, double productPrice)
        : title(productTitle), price(productPrice) {
    }

    void print() const {
        std::cout << title << ": " << price << std::endl;
    }
};

Почему это лучше, чем присваивание внутри тела конструктора?

  • поля создаются сразу с нужным значением;
  • это эффективнее для сложных объектов, например std::string;
  • только так можно инициализировать const-поля и ссылки;
  • такой код считается более идиоматичным для C++.

Пример с const-полем

Если поле объявлено как const, присвоить ему значение внутри тела конструктора уже нельзя. Его нужно именно инициализировать.

class Account {
private:
    const int id;
    double balance;

public:
    Account(int accountId, double startBalance)
        : id(accountId), balance(startBalance) {
    }
};

Это частая причина ошибок у новичков: они пытаются написать id = accountId; внутри конструктора и получают ошибку компиляции.

Перегрузка конструкторов

У класса может быть несколько конструкторов с разными параметрами. Это называется перегрузкой.

class Rectangle {
private:
    int width;
    int height;

public:
    Rectangle() : width(1), height(1) {
    }

    Rectangle(int size) : width(size), height(size) {
    }

    Rectangle(int w, int h) : width(w), height(h) {
    }

    int area() const {
        return width * height;
    }
};

int main() {
    Rectangle a;        // 1 x 1
    Rectangle b(5);     // 5 x 5
    Rectangle c(3, 4);  // 3 x 4

    std::cout << c.area() << std::endl;
}

Перегрузка удобна, но не стоит создавать слишком много вариантов без необходимости. Если логика становится запутанной, лучше использовать отдельные статические методы-фабрики или более простую модель класса.

Делегирующие конструкторы

Чтобы не дублировать код, один конструктор может вызывать другой. Это называется делегированием.

class Timer {
private:
    int seconds;

public:
    Timer() : Timer(0) {
    }

    Timer(int s) : seconds(s) {
    }
};

Конструктор Timer() передаёт работу конструктору Timer(int s). Это удобно, когда у вас есть один основной сценарий и несколько сокращённых.

Зачем нужен explicit

Если конструктор принимает один аргумент, C++ может использовать его для неявного преобразования типа. Иногда это приводит к неожиданному поведению.

class Meter {
private:
    int value;

public:
    explicit Meter(int v) : value(v) {
    }
};

void printDistance(Meter m) {
}

int main() {
    Meter distance(10);
    // printDistance(10); // Ошибка: explicit запрещает неявное преобразование
}

Совет: если конструктор с одним параметром не предназначен для преобразования типов, почти всегда добавляйте explicit.

Порядок инициализации полей

Важный нюанс: поля инициализируются не в порядке списка инициализации, а в порядке объявления в классе.

class Example {
private:
    int a;
    int b;

public:
    Example() : b(2), a(b) {
    }
};

Здесь может показаться, что сначала инициализируется b, а потом a. На самом деле сначала будет a, потому что оно объявлено выше. Поэтому правило простое: располагайте поля в списке инициализации в том же порядке, в котором они объявлены в классе.

= default и = delete

Иногда полезно явно попросить компилятор создать стандартный конструктор или, наоборот, запретить создание объектов определённым способом.

class Config {
public:
    Config() = default;
};

class Session {
public:
    Session() = delete;

    explicit Session(const std::string& token) {
        // создание только с токеном
    }
};

= delete хорошо показывает намерение: объект Session не должен существовать без токена.

Практические рекомендации

  • Используйте список инициализации почти всегда, особенно для строк, контейнеров, const-полей и ссылок.
  • Не оставляйте поля неинициализированными: у int, double и указателей может быть мусорное значение.
  • Добавляйте explicit к конструкторам с одним параметром.
  • Следите за порядком объявления полей.
  • Не помещайте в конструктор слишком много тяжёлой логики: загрузку файлов, сетевые запросы и сложные вычисления лучше выносить отдельно.

Если хотите системно разобраться не только с конструкторами, но и с классами, памятью, STL и реальными задачами, посмотрите курс «Программирование на C++ с Нуля до Гуру» — понятный путь от первых программ до уверенного владения C++.

Итог

Конструкторы в C++ отвечают за корректное начальное состояние объекта. Для простых классов достаточно значений по умолчанию, но в реальных программах часто нужны конструкторы с параметрами, списки инициализации, explicit, = default и = delete. Чем аккуратнее вы проектируете создание объектов, тем меньше ошибок появляется дальше в коде.

Копирование материалов разрешается только с указанием автора (Михаил Русаков) и индексируемой прямой ссылкой на сайт (https://myrusakov.ru)!

Добавляйтесь ко мне в друзья ВКонтакте: https://vk.com/myrusakov.
Если Вы хотите дать оценку мне и моей работе, то напишите её в моей группе: https://vk.com/rusakovmy.

Если Вы не хотите пропустить новые материалы на сайте,
то Вы можете подписаться на обновления: Подписаться на обновления

Если у Вас остались какие-либо вопросы, либо у Вас есть желание высказаться по поводу этой статьи, то Вы можете оставить свой комментарий внизу страницы.

Порекомендуйте эту статью друзьям:

Если Вам понравился сайт, то разместите ссылку на него (у себя на сайте, на форуме, в контакте):

  1. Кнопка:

    Она выглядит вот так: Как создать свой сайт

  2. Текстовая ссылка:

    Она выглядит вот так: Как создать свой сайт

  3. BB-код ссылки для форумов (например, можете поставить её в подписи):

Комментарии (0):

Для добавления комментариев надо войти в систему.
Если Вы ещё не зарегистрированы на сайте, то сначала зарегистрируйтесь.