std :: string值还是指针?

时间:2015-12-01 07:54:53

标签: c++ pointers

我从C ++开始,在理解如何将std::string作为参数传递给函数时遇到一些麻烦。

void foo(std::string text)
{
    // ...
}

std::string data = "Hello World!";
foo(data);

在这种情况下,如果我没错,字符串值将传递给该函数。因此,无论我对函数text中的foo变量做什么,它都不会对data变量产生任何影响。

但是,对于某些函数(例如std::getline),我怎么可能以完全相同的方式传递一个字符串并且它们会改变它的值?

std::string row;
std::getline(std::cin, row);
// now the value of row is changed

由于

4 个答案:

答案 0 :(得分:2)

通过引用传递:

void foo(std::string &text)
{
    // ...
}

答案 1 :(得分:2)

在C ++中,您有几个选择:

  1. 按值传递。函数原型为void foo(std::string text),您可以使用foo(data);调用它。您正确地注意到foodata中所做的任何修改都没有反映在调用方中。从概念上讲,我们会采用深层复制(如果这样做没有副作用,编译器可能会优化副本;但是你明智地不依赖它)。

  2. 通过引用传递。函数原型为void foo(std::string& text),您可以使用foo(data);调用它。 foodata 所做的任何修改都反映在来电者中。

  3. 通过const参考。函数原型为void foo(const std::string& text),您将其称为foo(data);。这是我的最爱:foo不是允许来修改data:这样的尝试会发出编译时错误。此外,不会删除该字符串的深层副本。

  4. 通过指针。函数原型为void foo(std::string* text),您将其称为foo(&data); foo 可以修改字符串。

  5. 通过const指针。函数原型为void foo(const std::string* text),您将其称为foo(&data);。与(3)中一样,foo无法修改传递的字符串。

  6. 因为1和2的调用语法是相同的,所以有些人不喜欢传递可以通过引用修改的内容,因为对调用者来说,参数可以更改是不明显的。

答案 2 :(得分:2)

您有几个选项可以在C ++中传递变量

1)按值

void foo(std::string value) { /* ... */ }
// ... call
foo(data);

std::string的复制构造函数用于在foo中创建本地实例,并且修改保留在本地实例中。

2)参考

void foo(std::string &value) { /* ... */ }
// ... call
foo(data);

引用了参数变量,因此value中的foo指向您传递给函数的同一对象。更改会反映在您的调用代码中。

3)通过const引用

void foo(const std::string &value) { /* ... */ }
// ... call
foo(data);

如在(2)中那样引用参数对象而不是创建新实例。但是,合同不是要修改value foo内的void foo(std::string *value) { /* ... */ } // ... call foo(&data); 。在内存和性能方面,这可能比(1)复制整个字符串更便宜。

4)通过指针

data

您将foo的地址作为参数传递给value。它类似于引用,仅依赖于指针逻辑。要访问(*value)中的字符串,您必须取消引用指针,如value->some_string_function()void foo(const std::string *value) { /* ... */ } // ... call foo(&data);

5)通过指向常量对象的指针

foo

与(4)类似,但指针引用的对象是常量,如参考案例(3)中所示。请注意,指针本身不是常量,因此可以将其指向不同的对象。但是,指针是本地的(指向的对象不是本地的),因此更改data内的指针地址对= link_to @post.user.name, @post.user 对象没有影响。

答案 3 :(得分:-1)

第二个参数是输出参数。 {{1}};