Образец кода:
MyItemType a;
MyItemType b;
a.someNumber = 5;
b = a;
cout << a.someNumber << endl;
cout << b.someNumber << endl;
b.someNumber = 10;
cout << a.someNumber << endl;
cout << b.someNumber << endl;
Выход:
5
5
5
10
Если бы a и b были ссылочными типами, последние 2 строки были бы 10 и 10 вместо 5 и 10, я думаю.
Означает ли это, когда вы делаете объявление, как это:
AClassType anInstance;
это рассматривается как тип значения?
——Вот MyItemType.h ————
#ifndef MYITEMTYPE_H
#define MYITEMTYPE_H
class MyItemType{
public:
int someNumber;
MyItemType();
};
MyItemType::MyItemType(){
}
#endif /* MYITEMTYPE_H */
На самом деле это не трактуется как тип значения.
В то время как в объектных переменных Java хранятся ссылки на объекты, в C ++ существует важное различие между объектом и его ссылкой. Назначение по умолчанию действительно по значению.
Если вы хотите, чтобы переменная была просто ссылкой, вы используете либо ссылку, либо тип указателя, в зависимости от того, что вы хотите с ней. Эти типы объявлены T*
а также T&
,
Чтобы проиллюстрировать это немного подробнее:
В Java, когда вы говорите MyClass obj
объект создан, но ссылка / указатель хранится в переменной obj
,
В C ++ MyClass obj
создает объект и сохраняет его в obj
, Если вы хотите работать со ссылками / указателями, вам нужно объявить переменные explicity как MyClass* objPointer
или же MyClass& objReference
,
В принципе, да (если вы считаете, что C ++ эквивалентен тому же значению, что и в Java).
AClassType anInstance;
это объект, а не ссылка. MyItemType a
а также
MyItemType b
это разные объекты, они находятся в разных местах памяти, поэтому, очевидно, что изменения одного не повлияют на другое.
Когда вы делаете a=b
вы не ссылаетесь на один объект с другим, но, в этом случае, выполняете членское присваивание. Это как сказать
a.someNumber = b.someNumber;
В C ++ объекты называются статическими (стековыми) переменными, когда они создаются без ссылки на указатель. Динамические (куча) переменные являются ссылками указателей, которые требуют ручного управления памятью.
В Java или C #, напротив, почти все объекты являются ссылочными типами, которые ведут себя как указатели, за исключением того, что они являются сборщиком мусора, тогда как типы значений являются специальным подмножеством всех объектов, которые обычно являются неизменяемыми. (Переменные стека C ++, безусловно, не являются неизменяемыми).
Хотя C ++ не вызывает объекты значения или ссылочные типы, поведение значения и ссылочных типов имеет эквивалентность в C ++.
Учитывая два объекта a
а также b
, a = b
:
b
в a
держать их как отдельные объекты;b
в a
, заставляя их ссылаться на один и тот же объект.Для C ++:
MyClass a; // value type
MyClass b; // value type
MyClass &c = a; // reference type (a reference in C++), fixed to a
MyClass *d = &b; // reference type (a pointer in C++)
a = b; // copy content of b into a
c = b; // copy content of b into a
d = &a; // set d to refer to a
*d = b; // copy content of b into a
Указатели / ссылки могут указывать на объекты значения, объекты, выделенные new
или какая-либо другая схема управления памятью (например, malloc
или Win32 CoTaskMalloc
).
Краткое объяснение в этой ключевой части
b = a;
Вы используете оператор присваивания копии, что означает этот знак здесь =
,
Поведение этого оператора по умолчанию заключается в применении копии по элементам, поэтому, если вы не определите / не перегрузите свой собственный оператор, эта строка скопирует все значения, хранящиеся во всех элементах a
в соответствующих членах b
,
new
Оператор — это совсем другая история, он часто используется для размещения объектов в куче и управления ими с помощью указателя, избегая стека и ненужных копий.