Может ли функция-член объекта изменить другой объект?

Сегодняшний вопрос заключается в том, может ли объект изменить другой объект того же типа класса? Например, представьте, что у класса есть некоторые личные данные. Мы создаем два объекта этого типа класса. Как один объект может изменить другой объект? Законно ли это делать?

Можем ли мы написать функцию-член, которая дает объекту возможность изменять другой объект того же типа класса? Это может быть полезно, если объект представляет бойца в видеоигре, и вы хотите дать одному бойцу возможность ранить другого.

Оказывается, это возможно сделать в C++. Мы хотим понять, почему C++ дает нам возможность сделать это. Для этого нужно сначала понять, что такое функция-член и как она работает. Прочитайте ответ на вопрос.

1 ответ

Здесь у нас есть class Bucket с двумя частными членами данных. Существует также конструктор, конструктор копирования и некоторые другие функции. Давайте обратим наше внимание на modifyOther функция. Он принимает один параметр, который является указателем на Bucket объект. Затем эта функция-член может редактировать этот другой Bucket объект.

#include <iostream>
using namespace std;

class Bucket {
  public:
    // Acts as constructor acceptint two arguments x and y,
    // one argument x,
    // or no arguments (default constructor).
    Bucket(int x = 0, int y = 0) : x(x), y(y) {}

    Bucket(const Bucket& rhs)
    {
        this->x = rhs.x;
        this->y = rhs.y;
    }

    void modifyOther(Bucket* other)
    {
        other->x = -1;
        other->y = 1;
    }

    void printInfo()
    {
        cout << "x = " << this->x << endl;
        cout << "y = " << this->y << endl;
        cout << endl;
    }
  private:
    int x;
    int y;
};


int main()
{
    Bucket a(10, 5);
    a.printInfo();

    Bucket b(8, 9);
    b.printInfo();

    a.modifyOther(&b);

    a.printInfo();
    b.printInfo();

    return 0;
}

в main() функция, мы объявляем два объекта class Base тип. Обратите внимание, что они имеют одинаковый тип данных. Это важно. Затем мы называем объект a"s modifyOther функция для успешного изменения внутренних закрытых данных членов объекта b,

Вот вывод этого кода:

x = 10
y = 5

x = 8
y = 9

x = 10
y = 5

x = -1
y = 1

Теперь вы можете подумать, не должно ли это быть незаконным? Разве частным данным не разрешен доступ только к самому объекту? Оказывается, что спецификаторы доступа к члену, такие как private а также public обеспечиваются компилятором, и компилятор не имеет понятия об отдельных объектах, только о классах.

private Доступ к элементам данных разрешен всем, кто находится внутри их класса, доступ к функциям-членам класса. поскольку modifyOther является функцией-членом типа class Base, он может получить доступ к private переменные int x а также int y и поменять их. Следовательно, здесь не нарушается ни одно правило.

Что такое функция-член? Это просто отдельная функция, которая принимает "невидимый" указатель на вызывающий объект и обращается к объекту через этот указатель. Этот указатель называется this, Посмотрите на printInfo функция. Есть причина, почему я использовал this->y указать переменные-члены. Потому что все функции-члены принимают "невидимый" this Указатель на вызывающий объект, функция на самом деле выглядит так:

void printInfo(Bucket* this)
{
    cout << "x = " << this->x << endl;
    cout << "y = " << this->y << endl;
    cout << endl;
    // this->x = -1;
}

Обратите внимание, что я специально добавил последнюю строку в эту функцию. Сравните определение printInfo функция к modifyOther функция. Они выглядят очень похожими. На самом деле единственная разница заключается в названии Bucket* параметр! Bucket* this является неявным указателем на вызывающий объект. Bucket* other это просто указатель на какой-то другой Bucket объект. Компилятор "тупой", он не может сказать разницу между этими двумя Bucket *на основе только их имен. Это относится к ним одинаково! Таким образом, мы можем сделать вывод, что тот же механизм, который используется для изменения вызывающего объекта, также может использоваться для изменения другого объекта того же типа класса.

Имейте в виду, что мы не можем использовать один и тот же прием для передачи указателя на объект другого класса и его модификации. Это не будет работать. Функция-член имеет доступ только к переменным одного класса! private означает, что переменная может быть изменена только функциями-членами этого конкретного класса, но не любыми другими. priavte переменная не может быть изменена внешним миром, поэтому внешний мир также включает в себя любые функции-члены разных классов.

Если вы не понимаете эту тему, пожалуйста, посмотрите на мой аналогичный вопрос о Stackru, а также посмотрите это видео на YouTube, которое я нашел при исследовании этой темы.

Существуют ли несколько функций-членов, скомпилированных для каждого объекта C++?

Что такое указатель "это"?

https://www.youtube.com/watch?v=_Wv-lEl1sgg&t=0s

Другие вопросы по тегам