#c
Вопрос:
Я новичок в C . Здесь, в моем случае, я создал два класса, class One
и class Two
. _x
объявляется как закрытая переменная-член class One
. Итак, здесь я пытаюсь изучить различные методы доступа к этой частной переменной( _x
) из любого другого класса(в данном случае это так class Two
). В основном это мой сценарий. Таким образом ,один из методов, который я попробовал, состоит в том, чтобы сделать class Two
в качестве friend class
class One
и для доступа к этой переменной, я использовал directValOfOne
функцию для печати значения этой переменной, а другой, который я пробовал, передавал адрес class One
экземпляра в другой функции-члене ( getDataTwo
) class Two
. До сих пор все работало хорошо.
Как вы можете видеть, я инициализировал _x
использование параметризованного конструктора, и печать этой переменной дает мне значение, как 10
при использовании обоих методов. Снова я изменил эту переменную, используя функцию настройки ( setDataOne
) 220
, и когда я печатаю ее с помощью getDataTwo
функции, она печатает значение как 220
. Но когда я попытался напечатать значение с помощью directValOfOne
, оно все еще показывало старое инициализированное значение ( 10
), которое я действительно запутался. Я напечатал адрес class One
объекта в этой directValOfOne
функции, и он показывает то же самое. Если это так, то почему новое значение( 220
) здесь не обновляется.
Исходный код размещен ниже.
#include <iostream>
using namespace std;
class One{
int _x;
public:
One(int a):_x{a} {}
//setters and getters
void setDataOne(int a) { _x = a; }
int getDataOne() const { return _x; }
//print values
void printOne() { cout<<"_x - "<<_x<<endl; }
friend class Two;
};
class Two{
One _a;
int id_one = 0;
public:
Two(One a):_a{a} {}
//setters and getters
void setDataTwo(int a) { }
int getDataTwo(One *obj) {
id_one = obj->getDataOne();
return id_one;
}
void printTwo() { printf("id_one = %dn",id_one); }
void directValOfOne() {
printf("address = %pn",amp;_a);
printf("_a._x = %dn",_a._x);
}
};
int main(){
One one(10);
Two two(one);
one.printOne();
two.getDataTwo(amp;one);
two.printTwo();
two.directValOfOne();
printf(" *********** n");
one.setDataOne(222);
one.printOne();
two.getDataTwo(amp;one);
two.printTwo();
two.directValOfOne();
return 0;
}
и вывод консоли будет,
_x - 10 id_one = 10 address = 006dfee4 _a._x = 10 *********** _x - 222 id_one = 222 address = 006dfee4 _a._x = 10
Как вы можете видеть _a._x
, по — прежнему выводится значение 10
. Но на самом деле _x
он обновляется до нового значения 220
. Извините, если я так подробно объяснил. Просто чтобы дать вам обзор, я подробно описал это.
Так что мой вопрос таков ,
Почему он не показывает обновленное значение, так как адреса совпадают?
Я упускаю здесь какую-то важную концепцию ? Если это так, пожалуйста, помогите мне разобраться в этой проблеме.
Комментарии:
1.
One _a;
является членомTwo
, и именно эти члены_x
печатаются с последним вызовомmain
. Этот элемент никогда не изменяется в этом коде после созданияtwo
, которому было присвоеноOne
значение10
хранения , для хранения путем копирования.2. Спасибо @WhozCraig. 1 за это . Проблема заключалась в копировании магазина. Теперь мне все ясно.
Ответ №1:
Проблема в вашем коде заключается в том, что вы передаете Two
экземпляр класса One
по значению. Это означает, что Two
хранится копия экземпляра One
, который вы передаете ему. При изменении значения _x
in one
это не влияет на значение _x
in _a
(внутри two
).
Для того, чтобы ваш код работал, вам необходимо передать ссылку One
на Two
конструктор in и сохранить эту ссылку. Теперь каждое изменение в one
также повлияет _a
.
Измененный код:
class Two{
Oneamp; _a;
int id_one = 0;
public:
Two(Oneamp; a):_a(a) {}
// ...
Что касается проблемы с адресом, адрес _a
останется прежним, так как нет причин для его изменения после инициализации. Если вы напечатаете адрес one
в своем текущем коде (до предлагаемых изменений), он должен быть по другому адресу, чем _a
(так _a
как это копия, которая находится где-то в другом месте).
В измененной версии кода вы должны увидеть тот же адрес, так как это один и тот же объект.
Комментарии:
1.О, ты его расколол. Спасибо, девочка, за объяснение. 1 за это :-). Но у меня все еще есть путаница в этой части адреса. Что вы подразумеваете под «напечатать адрес
one
в вашем текущем коде» ? Какие изменения мне нужно внести в свой код. Не могли бы вы, пожалуйста, уточнить в самом своем ответе.2. @VishnuCS Если вы напечатаете адрес
one
in main, вы увидите, что он отличается от адреса, напечатанного изнутриtwo
, когда он печатает адрес _a (потому что это два разных объекта).