Когда я использую строку в качестве параметра для метода, изменения в строке внутри функции не возвращаются обратно в вызывающую функцию. Простая причина Прохождение по значению.
Но при использовании вектора изменения в векторе отражаются обратно в вызывающей функции. Поэтому мой вопрос заключается в том, что проходящие векторы похожи на вызов по ссылке, где мы отправляем адрес в памяти, а не в переменную, поэтому любые изменения в функциях, возвращаемые обратно в функцию вызова
------------------------Обновить------------------------- -------
поэтому векторы должны быть переданы только по ссылке? Я не могу сделать это нормально?
конечно, вы можете пройти их нормально (это передать их по значению). но когда вы передаете объекты по значению, происходит то, что создается новый объект, а затем передаваемый вами объект копируется в новый объект. это, для стандартных типов (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 байта (размер переменной, содержащей адрес моего вектора)
Но при использовании вектора изменения в векторе отражаются обратно в вызывающей функции.
Это из-за прохождения по ссылке. Если вы передадите std::string
по ссылке, вы получите тот же эффект.
Обратное также верно: вы можете передать std::vector
по значению, если вы опускаете амперсанд в объявлении параметра. Это может иметь высокую стоимость, потому что все содержимое вектора будет скопировано.
поэтому векторы должны быть переданы только по ссылке?
Они не должны передаваться по ссылке, но во многих случаях передача по стоимости просто слишком дорога, поэтому людям это редко случается. Что касается sizeof(v)
, вы получаете только небольшой размер вектора, который выделяется самим векторным объектом (в этом случае он находится в стеке). Существует также динамическая часть, на которую указывают указатели внутри вектора, которые не учитываются оператором sizeof
.
Предполагая, что это действительно вопрос 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.
Я хотел потратить время, чтобы указать, что String - особый случай. Строка - это последний класс, который означает, что он неизменен и не может быть изменен.
final
, не делает его неизменным.
final
означает, что вы не можете объявить класс, extends String
. Другие вещи делают его неизменным.