Может ли функция-член объекта изменить другой объект?
Сегодняшний вопрос заключается в том, может ли объект изменить другой объект того же типа класса? Например, представьте, что у класса есть некоторые личные данные. Мы создаем два объекта этого типа класса. Как один объект может изменить другой объект? Законно ли это делать?
Можем ли мы написать функцию-член, которая дает объекту возможность изменять другой объект того же типа класса? Это может быть полезно, если объект представляет бойца в видеоигре, и вы хотите дать одному бойцу возможность ранить другого.
Оказывается, это возможно сделать в 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++?