2014-02-26 29 views
0

当我使用字符串作为方法的参数时,函数内字符串的更改不会反映回调用函数。简单的理由按价值传递。字符串和向量作为方法参数的区别

但是,当使用矢量时,对矢量的更改会反映回调用函数中。所以我的问题是传递矢量是否像通过引用调用我们在内存中发送地址而不是变量,因此函数内的任何更改都会反映回调用函数

--------- ---------------更新--------------------------------

所以载体只能通过参考传递?我不能这样做吗?

当然,您可以正常传递它们(即按值传递它们)。但是当你通过值传递对象时会发生什么是一个新的对象被创建,然后你传递的对象被复制到新的对象。对于标准类型(char,int,float等)来说,这是可以的,因为标准类型的大小很小(char是一个字节,short是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++的问题吗? – ajb

回答

5

但是,当使用一个矢量时,向量的变化会反映回调用函数中。

这是因为通过引用。如果您通过引用传递std::string,您将获得相同的效果。

反过来也是如此:如果您在参数声明中省略了&符号,则可以按值传递std::vector。但是,这可能会带来很高的成本,因为矢量的全部内容都将被复制。

所以矢量只能通过引用传递?

他们不一定要通过引用传递,但在许多情况下,传递值是非常昂贵的,所以人们很少这样做。就sizeof(v)而言,您只会获得与矢量对象本身一起分配的矢量的小尺寸(在本例中,它位于堆栈上)。还有一个动态部分指向矢量内的指针,这不是由sizeof运算符说明的。

+0

+1,因为“他们(std :: vectors)不必通过引用传递,但是在许多情况下,传递值是非常昂贵的”,特别是。如果我有一个向量,并且需要某个对象才能使用它,那么我通常只需通过引用传递该向量,然后继续处理它。即使这种情况很少发生,我也许会避免通过价值传递,因为我不打算复制甚至可能为50MB的内容。 –

1

我想花时间指出,字符串是一个特殊的案件。字符串是一个最终的类,这意味着它是不可变的,不能被修改。

+0

它是'final'的事实并不能使它不可变。 –

+0

'final'意味着你不能声明一个'extends String'的类。其他的东西使它不可变。 – ajb

1

假设这是真的一个Java问题:

两个StringVector类型是按值传递(但传递的值实际上是一个参考)。试想一下:

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的对象。但是我不能举一个真实的例子,因为String对象在Java中是不可变的。

+1

@SotiriosDelimanolis谢谢你捕捉我的哑巴错误... – ajb

相关问题