В чем разница между передачей по ссылке и передачей по значению?

Чтобы обрабатывать элементы вектора indexmatrix(row, :) как отдельные индексы, вам нужны элементы в виде массива ячеек. Итак, вы можете сделать что-то вроде этого

subsCell = num2cell( indexmatrix( row, : ) );
finalTable( row ) = kDimensionalMatrix( subsCell{:} );

Чтобы развернуть subscell как список, разделенный запятыми, вам, к сожалению, нужны две отдельные строки. Однако этот код не зависит от k.

523
задан Deduplicator 19 July 2014 в 17:28
поделиться

7 ответов

Примеры:

class Dog 
{ 
public:
    barkAt( const std::string& pOtherDog ); // const reference
    barkAt( std::string pOtherDog ); // value
};

const & является обычно лучшим. Вы не подвергаетесь штраф разрушения и конструкция. Если ссылка не является константой, Ваш интерфейс предполагает, что это изменит переданный в данных.

3
ответ дан Deduplicator 19 July 2014 в 17:28
поделиться

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

18
ответ дан Craig 19 July 2014 в 17:28
поделиться
  • 1
    It' s хороший, чтобы советовать использовать правильный инструмент для задания! – xtofl 23 December 2008 в 16:02

Существенное различие между ними - то, что значения хранилища переменных типа значения, таким образом определяя переменную типа значения в вызове метода передают копию значения той переменной к методу. Переменные ссылочного типа хранят ссылки на объекты, таким образом определяя переменную ссылочного типа, поскольку аргумент передает метод копия фактической ссылки, которая относится к объекту. Даже при том, что сама ссылка передается значением, метод может все еще использовать ссылку, которую это получает для взаимодействия with— и возможно modify— исходный объект. Точно так же при возврате информации из метода через оператор возврата, метод возвращает копию значения, сохраненного в переменной типа значения или копии ссылки, сохраненной в переменной ссылочного типа. Когда ссылка возвращается, вызывающий метод может использовать ту ссылку для взаимодействия со ссылочным объектом. Так, в действительности объекты всегда передаются ссылкой.

В c#, для передачи переменной ссылкой, таким образом, вызываемый метод может изменить переменную, C# обеспечивает ключевые слова касательно и. Применение касательно ключевого слова к объявлению параметра позволяет, Вы для передачи переменной методу reference— вызываемый метод будете в состоянии изменить исходную переменную в вызывающей стороне. Касательно ключевого слова используется для переменных, которые уже были инициализированы в вызывающем методе. Обычно, когда вызов метода содержит неинициализированную переменную как аргумент, компилятор генерирует ошибку. Предшествование параметру с ключевым словом создает выходной параметр. Это указывает к компилятору, что аргумент будет передан в вызываемый метод ссылкой и что вызываемый метод присвоит значение исходной переменной в вызывающей стороне. Если метод не присваивает значение выходному параметру в каждом возможном пути выполнения, компилятор генерирует ошибку. Это также препятствует тому, чтобы компилятор генерировал сообщение об ошибке для неинициализированной переменной, которая передается как аргумент методу. Метод может возвратить только одно значение своей вызывающей стороне через оператор возврата, но может возвратить много значений путем определения нескольких вывод (касательно и/или) параметры.

см. c# обсуждение и примеры здесь текст ссылки

5
ответ дан Tina Endresen 19 July 2014 в 17:28
поделиться

Вот пример:

#include <iostream>

void by_val(int arg) { arg += 2; }
void by_ref(int&arg) { arg += 2; }

int main()
{
    int x = 0;
    by_val(x); std::cout << x << std::endl;  // prints 0
    by_ref(x); std::cout << x << std::endl;  // prints 2

    int y = 0;
    by_ref(y); std::cout << y << std::endl;  // prints 2
    by_val(y); std::cout << y << std::endl;  // prints 2
}
53
ответ дан Deduplicator 19 July 2014 в 17:28
поделиться
  • 1
    Выезд curlpp - обертка C++ для ВИХРЕВОЙ библиотеки – Piotr Dobrogost 7 May 2009 в 11:08

Это - путь, как передать аргументы функциям. Передача ссылкой означает, что параметр вызванных функций совпадет с передаваемым аргументом вызывающих сторон (не значение, но идентификационные данные - сама переменная). Передача значением означает, что параметр вызванных функций будет копией передаваемого аргумента вызывающих сторон. Значение будет тем же, но идентификационные данные - переменная - отличается. Таким образом изменения в параметре, сделанном вызванной функцией в одном случае, изменяются, аргумент передал, и в другом случае просто изменяет значение параметра в вызванной функции (который является только копией). В быстрой спешке:

  • Java только поддерживает передачу значением. Всегда аргументы копий, даже при том, что при копировании ссылки на объект, параметр в вызванной функции укажет на тот же объект, и изменения в том объекте будут, посмотрите в вызывающей стороне. Так как это может сбивать с толку, здесь то, что Jon Skeet должен сказать об этом.
  • C# поддерживает передачу значением и передачу ссылкой (ключевое слово ref, используемое в вызывающей стороне и вызванной функции). У Jon Skeet также есть хорошее объяснение этого здесь .
  • C++ поддерживает передачу значением и передачу ссылкой (тип параметра ссылки, используемый в вызванной функции). Вы найдете ниже объяснение этого.

Коды

, Так как мой язык является C++, я буду использовать это здесь

// passes a pointer (called reference in java) to an integer
void call_by_value(int *p) { // :1
    p = NULL;
}

// passes an integer
void call_by_value(int p) { // :2
    p = 42;
}

// passes an integer by reference
void call_by_reference(int & p) { // :3
    p = 42;
}

// this is the java style of passing references. NULL is called "null" there.
void call_by_value_special(int *p) { // :4
    *p = 10; // changes what p points to ("what p references" in java)
    // only changes the value of the parameter, but *not* of 
    // the argument passed by the caller. thus it's pass-by-value:
    p = NULL;
}

int main() {
    int value = 10;
    int * pointer = &value;

    call_by_value(pointer); // :1
    assert(pointer == &value); // pointer was copied

    call_by_value(value); // :2
    assert(value == 10); // value was copied

    call_by_reference(value); // :3
    assert(value == 42); // value was passed by reference

    call_by_value_special(pointer); // :4
    // pointer was copied but what pointer references was changed.
    assert(value == 10 && pointer == &value);
}

, И пример в Java не причинит боль:

class Example {
    int value = 0;

    // similar to :4 case in the c++ example
    static void accept_reference(Example e) { // :1
        e.value++; // will change the referenced object
        e = null; // will only change the parameter
    }

    // similar to the :2 case in the c++ example
    static void accept_primitive(int v) { // :2
        v++; // will only change the parameter
    }        

    public static void main(String... args) {
        int value = 0;
        Example ref = new Example(); // reference

        // note what we pass is the reference, not the object. we can't 
        // pass objects. The reference is copied (pass-by-value).
        accept_reference(ref); // :1
        assert ref != null && ref.value == 1;

        // the primitive int variable is copied
        accept_primitive(value); // :2
        assert value == 0;
    }
}

Википедия

http://en.wikipedia.org/wiki/Pass_by_reference#Call_by_value

http://en.wikipedia.org/wiki/Pass_by_reference#Call_by_reference

Этот парень в значительной степени закрепляет его:

http://javadude.com/articles/passbyvalue.htm

134
ответ дан 10 revs, 2 users 97% 19 July 2014 в 17:28
поделиться

Передача значением отправляет КОПИЮ данных, хранивших в переменной, которую Вы определяете, передача ссылкой отправляет прямую ссылку к самой переменной. Таким образом, если Вы передаете переменную ссылкой и затем заменяете переменную в блоке, Вы передали его в, исходная переменная будет заменена. Если Вы просто передадите значением, исходная переменная не будет в состоянии быть замененной блоком, в который Вы передали его, но Вы получите копию того, что это содержало во время вызова.

11
ответ дан MetaGuru 19 July 2014 в 17:28
поделиться

Прежде всего "передача значением по сравнению с передачей ссылочным" различием, как определено в теории CS теперь устаревшая , потому что техника, первоначально определенная как "передача ссылкой", с тех пор впала в немилость и редко используется теперь. <глоток> 1

Более новые языки <глоток> 2 имеют тенденцию использовать различное (но подобный) пара методов для достижения тех же эффектов (см. ниже), который является основным источником беспорядка.

А вторичный источник беспорядка является тем, что в "передаче ссылкой", "ссылка" имеет более узкое значение, чем общий термин "ссылка" (потому что фраза предшествует ему).

<час>

Теперь, подлинное определение:

  • , Когда параметр передан ссылкой , вызывающая сторона и вызываемый используют ту же переменную для параметра. Если вызываемый изменяет переменную параметра, эффект видим к переменной вызывающей стороны.

  • , Когда параметр передан значением , вызывающая сторона и вызываемый имеют две независимые переменные с тем же значением. Если вызываемый изменяет переменную параметра, эффект не видим вызывающей стороне.

Вещи отметить в этом определении:

  • "Переменная" здесь означает вызывающую сторону (локальный или глобальный) сама переменная - т.е. если я передам локальную переменную ссылкой и присвою ей, я заменю саму переменную вызывающей стороны, не, например, независимо от того, что она указывает, если это - указатель.

    • Это теперь считают плохой практикой (как неявную зависимость). По сути, фактически все более новые языки исключительно, или почти исключительно передача значением. Передача ссылкой теперь в основном используется в форме "output/inout аргументы" на языках, куда функция не может возвратить больше чем одно значение.
  • значение "ссылки" в "передаче ссылкой" . Различие с общим "ссылочным" термином, то, что эта "ссылка" является временной и неявной. то, Что в основном получает вызываемый, "переменная", которая является так или иначе "тем же" как исходным. то, Как конкретно этот эффект достигается, не важно (например, язык может также представить некоторые детали реализации - адреса, указатели, разыменовав - это все не важно; если результирующий эффект - это, это - передача ссылкой).

<час>

Теперь, на современных языках, переменные имеют тенденцию быть "ссылочных типов" (другое понятие, изобретенное позже, чем "передача ссылкой" и вдохновлены им), т.е. данные фактического объекта хранятся отдельно где-нибудь (обычно на "куче"), и только "ссылки" на него когда-либо сохранены в переменных и передаются как параметры. <глоток> 3

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

  • , Если ссылка просто взята от переменной вызывающей стороны и передана как аргумент, это имеет тот же эффект как передача ссылкой: если отнесенный объект , видоизменился в вызываемом, вызывающая сторона будет видеть изменение.
    • Однако, если переменная, содержащая эту ссылку, reassiged, , это прекратит указывать на тот объект, таким образом, дальнейшие операции на этой переменной будут вместо этого влиять на то, на что это указывает теперь.
  • , Чтобы иметь тот же эффект как передача значением, копия объекта сделана в какой-то момент. Опции включают:
    • вызывающая сторона может просто сделать частную копию перед вызовом и дать вызываемому ссылку на это вместо этого.
    • На некоторых языках, некоторые типы объектов "неизменны": любая операция на них, которая, кажется, изменяет значение на самом деле, создает абсолютно новый объект, не влияя на исходный. Так, передача объекта такого типа как аргумент всегда имеет эффект передачи значением: копия для вызываемого будет сделана автоматически, если и когда ей будет нужно изменение, и объект вызывающей стороны никогда не будет затрагиваться.
        <литий> На функциональных языках, весь объекты неизменны.

, Как можно видеть, эта пара методов, является почти тем же как теми в определении, только с уровнем абстракции: просто замените "переменную" "ссылочным объектом".

существует не согласован имя их, которое приводит к искаженным объяснениям как "вызов по значению, где значение является ссылкой". В 1975 Barbara Liskov предложила термин" call-by-object-sharing" (или иногда просто "вызов совместным использованием"), хотя это никогда вполне завоевало популярность. Кроме того, ни одна из этих фраз не проводит параллель с исходной парой. Неудивительный старые условия закончили тем, что были снова использованы в отсутствие чего-либо лучше, ведя к беспорядку. <глоток> 4

<час>

ПРИМЕЧАНИЕ : В течение долгого времени этот ответ раньше говорил:

Говорят, что я хочу совместно использовать веб-страницу с Вами. Если я говорю Вам URL, я являюсь передающим ссылкой. Можно использовать тот URL, чтобы видеть, что та же веб-страница I видит. Если та страница изменяется, мы видим изменения. При удалении URL все, что Вы делаете, уничтожает Вашу ссылку на ту страницу - Вы не удаляете саму фактическую страницу.

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

Это главным образом корректно кроме более узкое значение "ссылки" - это являющийся и временным и неявным (это не имеет к, но быть явным и/или персистентным дополнительные функции, не часть семантической передачи ссылкой, как объяснено выше). Более близкая аналогия дала бы Вам копию документа по сравнению с приглашением Вас работать над оригиналом.

<час>

<глоток> 1 , Если Вы не программируете в Фортране или Visual Basic, это не поведение по умолчанию, и на большинстве языков в современном использовании, истинный вызов по ссылке даже не возможен.

<глоток> 2 изрядное количество А более старых поддерживает его, также

<глоток> 3 На нескольких современных языках, все типы являются ссылочными типами. Этот подход был введен впервые CLU языка в 1975 и был с тех пор принят многими другими языками, включая Python и Ruby. И намного больше языков использует гибридный подход, где некоторые типы являются "типами значения", и другие являются "ссылочными типами" - среди них, C#, Java и JavaScript.

<глоток> 4 нет ничего плохо с переработкой подходящего старого термина по сути, , но нужно так или иначе прояснить, какое значение используется каждый раз. Не выполнение, которое является точно, что продолжает вызывать беспорядок.

1029
ответ дан 11 revs, 4 users 51% 19 July 2014 в 17:28
поделиться
  • 1
    : состояние при наведении курсора будет не только работать в Firefox, но любом главном браузере неIE (Opera, Konqueror, Safari, и др.). – Nick Presta 11 May 2009 в 16:34
Другие вопросы по тегам:

Похожие вопросы: