Объектные переменные в C ++ содержат значения, а не ссылки на объекты - PullRequest
6 голосов
/ 24 января 2011

В: http://www.horstmann.com/ccj2/ccjapp3.html, в A3.4. Объекты , упоминается следующее:

В C ++ переменные объекта содержат значения, а не ссылки на объекты

Вы можете уточнить этот момент? И только ли pointer в C ++ содержит ссылки на объекты?

Можем ли мы сказать, что object reference - это object address?

Спасибо.

Ответы [ 8 ]

6 голосов
/ 24 января 2011

Вы можете уточнить этот момент?

Лучше понять по сравнению, например, с Java или C #:

MyClass a = new MyClass; // creates an instance.
MyClass b = a; // we still have one instance of MyClass in memory

В отличие от C ++:

MyClass a; // a *is* an instance of MyClass.
MyClass b = a; // we make a copy of a, now there are *two* instances of MyClass.

И только указатель в C ++ содержит ссылки на объекты?

Нет, ссылки тоже.

Можем ли мы сказать, что ссылка на объект является адресом объекта?

Нет, если вы имеете в виду ссылку A&, то это деталь реализации. Также вы можете реализовать объекты со ссылочной семантикой, которые работают как в C #. xml_node в библиотеке pugixml является примером:

xml_node root = ...;
xml_node root2 = root; // doesn't copy the document
// root2 refers to the same object as root.
4 голосов
/ 24 января 2011

C ++ поддерживает понятия значение / указатель / ссылка.Значение похоже на Java int, если вы передаете его функции, которая изменяет аргумент, исходное значение не изменяется, это называется семантикой значения.

В Java большинство объектов имеют ссылочную семантику, что означаетчто переменная не хранит объект, она сохраняет ссылку на объект, так что если объект изменяется с помощью одной ссылки, все остальные ссылки видят изменения.Это также поддерживается в C ++ со ссылками и указателями.Указатели - это адрес памяти объекта, а ссылки ведут себя семантически схожим образом (и обычно реализуются с указателями за кулисами).Неправильно говорить, что ссылка - это адрес объекта, адрес объекта - это указатель на объект.

Подробнее см. Семантика ссылки и значения .

2 голосов
/ 24 января 2011

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

Ссылки (смысл C ++, а не Java) не являются объектными переменными (в текущем стандарте я считаю, что в c ++ 0x есть некоторые изменения), а скорее псевдонимы к объектам.Вокруг этого есть несколько технических деталей, например, тот факт, что вы можете создавать массивы объектов, но вы не можете создавать массивы ссылок (ссылки не являются объектами).

Теперь, если вы пришли изФон Java, что вам действительно нужно помнить, это то, что (хотя и не совсем одинаковые) переменные Java и указатели C ++ - это схожие вещи: они содержат ключ для доступа к объекту где-то, но концепция ссылки на C ++ недоступна в Java.По этой причине вы не можете реализовать swap операцию в Java, за исключением некоторых конкретных типов:

template <typename T>
void swap( T & lhs, T & rhs )
{
   T tmp = lhs;
   lhs = rhs;
   rhs = tmp;
}
int main() {
   int a = 1, b = 5; 
   swap( a, b );      // a == 5, b == 1 after this call in this context
}

Если вы помните об этом и понимаете, что в Java ссылки передаются по значению (aкопия ссылки передается в функцию), тогда вы сделали хороший шаг в понимании семантики вызова функций C ++.

1 голос
/ 24 января 2011

Один из наиболее наглядных способов интерпретировать разницу между переменными объекта и переменными-указателями связан с местом, где выделяется память: переменные объекта ссылаются на объекты стека, а указатели (и ссылки) могут ссылаться (обычно) на кучуобъекты.Оба построены по-разному, имеют разные жизненные периоды, и у каждого есть свои преимущества и недостатки.

Ознакомьтесь с разделом "Стек и куча" моей статьи: http://akos.ma/188y

1 голос
/ 24 января 2011

На самом деле в C ++ есть три разных типа переменных. Значения, ссылки и указатели. Первое значение value означает, что если вы определите

int a;

или

SomeOtherType a;

и это означает, что вы создаете новый объект этого типа, и память резервируется для его хранения. И тогда вы можете, например, скопировать его содержимое в другую переменную, написав

another_variable = a;

Если вместо этого вы используете указатели, например:

SomeType *a = &some_existing_variable;

тогда, если вы скажете "b = a;" где a и b оба являются указателями, вы не копируете данные, а просто изменяете, на какой объект указывают эти указатели. Ссылки работают так же. Наиболее важные различия между указателями и ссылками заключаются в том, что ссылка не может быть NULL, вы должны инициализировать ссылку, вы не можете изменить значение ссылки и что синтаксис для использования с ними отличается.

1 голос
/ 24 января 2011

В C ++ по умолчанию передаются и хранятся объекты по значению. Так что если у вас есть

class A {
    int x[5000];
}

Это создает тип, который хранит 5000 дюймов. Если у вас есть класс, который использует A, например:

class B {
    A content;
};

тогда каждый B содержит массив из 5000 дюймов. Это контрастирует с таким языком, как Java, где содержимое будет выглядеть как указатель на A.

В C ++ у вас есть возможность сделать содержимое указателем на A:

class C {
    A* content;
};

или ссылка на A

class D {
    A& content;
};

но вы должны сделать это явно. Кроме того, ссылки в C ++ не могут быть нулевыми, поэтому, если существует вероятность, что значение содержимого не определено, вы должны использовать указатель.

1 голос
/ 24 января 2011

Да, в C ++ указатели содержат ссылки на объекты, есть оператор &, который также делает косвенную ссылку. Java и C ++ имеют разное поведение. IN java:

myobject a;
a = new myobject();

В C ++:

myobject a;

или myobject * a; a = новый myobject ();

1 голос
/ 24 января 2011

Ссылка на объект - это постоянный, фиксированный и неявный адрес объекта. Принимая во внимание, что указатель является изменяемой, явной переменной адреса. Другими словами, ссылка использует адрес объекта для доступа к объекту, но 1) она не делает этот адрес доступным для программиста, и 2) ссылка постоянно связана с конкретным объектом. Указатель может указывать на любой объект определенного типа или вообще без объекта. Инициализация не является обязательной. Кроме того, поскольку указатель является переменной, он может быть переназначен по желанию.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...