Смысл this в C++ / self в Python

259
22 января 2018, 08:18

В чем суть self в ООП языка Python и this в C++ (лучше в примерах)?

Answer 1

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

  1. Обращаться к собственным полям (т.е, переменным) и методам;
  2. Передавать объекту самого себя в другие функции и объекты.

Python и C++ отличаются тем, что первая часть в C++ (ещё в Java, C# и Objective-C) реализована автоматически, нам не нужно постоянно прописывать self или this. Однако это порождает либо путаницу между переменными объекта и локальными, либо постоянное использование нижнего подчёркивания в названии переменных, что, на мой взгляд, не сильно лучше ссылки на объект. Наоборот, в Питоне (и, например, JavaScript'e) нужно всегда явно указывать, если обращение идёт к переменной текущего объекта.

Рассмотрим оба варианта использования.

1) Для обращения к своим полям

Например, возьмём класс прямоугольник, у него есть две переменные с длинами сторон: a и b, нам нужен метод для вычисления площади – а для этого нужно обращаться из метода к переменным объекта. Python:

class Rect:
    def __init__(self, a, b):
        self.a = a
        self.b = b
    def area(self):
        return self.a * self.b

C++:

class Rect {
    private:
        int _a, _b;
    public:
        Rect(int a, int b) {
            // вот почему используется нижнее подчёркивание
            _a = a;
            _b = b;
        }
        // self/this нет ни в методе, ни у переменных
        int area() {
            return _a * _b;
        }
}

Обратите внимание на то, что в методах на Питоне self всегда указывается явно, а в C++ this принимает значение автоматически. И хотя конструкция применяется одна и та же object.method(data), а в объявлении методов this не используется, на самом деле ссылка на объект присутствует как скрытый первый аргумент. Можно указать объект и явным образом, вот две эквивалентные строки C++ кода:

my_object.push(3);
MyClass::push(&my_object, 3);
// надеюсь, Вы понимаете C++ значение символов & и *
// если нет, спешите скорее разузнать

Для класса такого вида:

class MyClass {
    ...
    void push(int number) {
        ...
    }
}

2) Для передачи текущего объекта

Например, у нас есть какой-нибудь объект контроллер или контейнер, и объекты нашего класса должны автоматически туда положиться или удалиться из него. Python:

all = []
class MyClass:
    def __init__(self):
        all.append(self)

C++:

class MyClass {
public:
    MyClass();
}
vector<MyClass*> all = new vector<MyClass*>();
MyClass::MyClass() {
    all.push(this);
}
READ ALSO
Подключение Qt к &ldquo;Empty project&rdquo; в VS15

Подключение Qt к “Empty project” в VS15

Проект запускается, но есть проблемы:

259
Выдача содержимого каталога

Выдача содержимого каталога

Как написать код, который выдает содержимое указанного каталога подобно команде ls??

249
Загрузка даты из qCalendarWidget

Загрузка даты из qCalendarWidget

Нужно чтобы при выборе даты в qCalendarWidget и нажатии на кнопку qButton дата переносилась в базу данных MySQLКак это реализовать? C++

182