Разница между строкой и вектором в качестве параметров метода

0

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

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

------------------------Обновить------------------------- -------

поэтому векторы должны быть переданы только по ссылке? Я не могу сделать это нормально?

конечно, вы можете пройти их нормально (это передать их по значению). но когда вы передаете объекты по значению, происходит то, что создается новый объект, а затем передаваемый вами объект копируется в новый объект. это, для стандартных типов (char, int, float и т.д.) в порядке, поскольку стандартные типы невелики по размеру (char - один байт, короткий - 2, int - 2 или 4, long - 4 и т.д.). однако вектор не такой маленький. Попробуйте сделать это:

1
2
3
4
5
6
7
8
9
10
11
12

#include <iostream>
#include <vector>
using namespace std;

int main()
{
     vector<int> v;
     cout << sizeof(v) << endl;

     system("pause");
     return 0;
}

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

  • 0
    Нет, все в Java передается по значению. Мы должны увидеть, что вы делаете с аргументом. Переопределение переменной параметра не отражается в аргументе из вызывающего кода.
  • 1
    Это должен быть вопрос C ++?
Теги:

3 ответа

5
Лучший ответ

Но при использовании вектора изменения в векторе отражаются обратно в вызывающей функции.

Это из-за прохождения по ссылке. Если вы передадите std::string по ссылке, вы получите тот же эффект.

Обратное также верно: вы можете передать std::vector по значению, если вы опускаете амперсанд в объявлении параметра. Это может иметь высокую стоимость, потому что все содержимое вектора будет скопировано.

поэтому векторы должны быть переданы только по ссылке?

Они не должны передаваться по ссылке, но во многих случаях передача по стоимости просто слишком дорога, поэтому людям это редко случается. Что касается sizeof(v), вы получаете только небольшой размер вектора, который выделяется самим векторным объектом (в этом случае он находится в стеке). Существует также динамическая часть, на которую указывают указатели внутри вектора, которые не учитываются оператором sizeof.

  • 0
    +1, для «Они (std :: vectors) не должны передаваться по ссылке, но во многих случаях передача по значению просто слишком дорога», особенно. Если у меня есть вектор и мне нужен какой-то объект, чтобы я мог его использовать, я обычно просто передаю вектор по ссылке и сохраняю для него указатель. Даже если это случается редко, я, вероятно, избегу передачи по значению, поскольку я не собираюсь копировать то, что может быть даже 50 МБ.
1

Предполагая, что это действительно вопрос Java:

Оба типа String и Vector передаются по значению (но переданное значение фактически является ссылкой). Рассматривать:

void foo1 (String s) {
    s = new String("abcde");
}

void foo2 (Vector<Integer> v) {
    v = new Vector<Integer> ();
}

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

Если вы делаете что-то, что изменяет вектор, хотя:

void foo3 (Vector<Integer> v) {
    v.add (10);
}

это изменяет объект, на который указывает v. Если был метод, который модифицировал String, например:

void foo4 (String s) {
    s.setChar(0, '!');  // does not exist in Java
        // but pretend that it changes the first character of the string
} 

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

  • 1
    @SotiriosDelimanolis спасибо, что поймали мою глупую ошибку ...
1

Я хотел потратить время, чтобы указать, что String - особый случай. Строка - это последний класс, который означает, что он неизменен и не может быть изменен.

  • 0
    Тот факт, что он является final , не делает его неизменным.
  • 0
    final означает, что вы не можете объявить класс, extends String . Другие вещи делают его неизменным.

Ещё вопросы

Сообщество Overcoder
Наверх
Меню