'&'在C++声明中做了什么?

pou*_*def 39 c++ syntax operators

我是一个C人,我正在尝试理解一些C++代码.我有以下函数声明:

int foo(const string &myname) {
  cout << "called foo for: " << myname << endl;
  return 0;
}
Run Code Online (Sandbox Code Playgroud)

函数签名与等效的C有何不同:

int foo(const char *myname)
Run Code Online (Sandbox Code Playgroud)

使用string *mynamevs 之间有区别string &myname吗?&用C++和*C表示指针有什么区别?

同理:

const string &GetMethodName() { ... }
Run Code Online (Sandbox Code Playgroud)

这是&做什么的?是否有一些网站解释了如何&在C vs C++中使用不同的方式?

czu*_*ger 33

"&"表示引用而不是指向对象的指针(在您的情况下是常量引用).

具有诸如此类功能的优点

foo(string const& myname) 
Run Code Online (Sandbox Code Playgroud)

过度

foo(string const* myname)
Run Code Online (Sandbox Code Playgroud)

在前一种情况下,您可以保证myname为非null,因为C++不允许NULL引用.由于您通过引用传递,因此不会复制该对象,就像传递指针一样.

你的第二个例子:

const string &GetMethodName() { ... }
Run Code Online (Sandbox Code Playgroud)

允许您返回常量引用,例如,成员变量.如果您不希望返回副本,并且再次保证返回的值为非null,则此选项非常有用.例如,以下内容允许您直接进行只读访问:

class A
{
  public:
  int bar() const {return someValue;}
  //Big, expensive to copy class
}

class B
{
public:
 A const& getA() { return mA;}
private:
 A mA;
}
void someFunction()
{
 B b = B();
 //Access A, ability to call const functions on A
 //No need to check for null, since reference is guaranteed to be valid.
 int value = b.getA().bar(); 
}
Run Code Online (Sandbox Code Playgroud)

您当然要小心不要返回无效的引用.编译器将很乐意编译以下内容(取决于您的警告级别以及您如何处理警告)

int const& foo() 
{
 int a;

 //This is very bad, returning reference to something on the stack. This will
 //crash at runtime.
 return a; 
}
Run Code Online (Sandbox Code Playgroud)

基本上,您有责任确保您返回的任何内容实际上都是有效的.


Vic*_*let 17

这里,&不用作运算符.作为函数或变量声明的一部分,&表示引用.C++ FAQ Lite 在引用方面有一个非常好的章节.


soh*_*hum 8

string*和string&以两种方式不同.首先,指针指向数据的地址位置.参考指向数据.如果您具有以下功能:

int foo(string *param1);
Run Code Online (Sandbox Code Playgroud)

您必须检查函数声明以确保param1指向有效位置.比较:

int foo(string &param1);
Run Code Online (Sandbox Code Playgroud)

在这里,调用者有责任确保指向的数据有效.您不能传递"NULL"值,例如,在上面的第二个函数中.

关于第二个问题,关于方法返回值是一个引用,请考虑以下三个函数:

string &foo();
string *foo();
string foo();
Run Code Online (Sandbox Code Playgroud)

在第一种情况下,您将返回对数据的引用.如果您的函数声明如下所示:

string &foo()
{
    string localString = "Hello!";
    return localString;
}
Run Code Online (Sandbox Code Playgroud)

您可能会收到一些编译器错误,因为您正在返回对该函数的堆栈中初始化的字符串的引用.在函数返回时,该数据位置不再有效.通常,您希望返回对类成员或类似内容的引用.

上面的第二个函数在实际内存中返回一个指针,因此它将保持不变.但是,您必须检查NULL指针.

最后,在第三种情况下,返回的数据将被复制到调用者的返回值中.所以如果你的功能是这样的:

string foo()
{
    string localString = "Hello!";
    return localString;
}
Run Code Online (Sandbox Code Playgroud)

你没事,因为字符串"Hello"将被复制到该函数的返回值中,可以在调用者的内存空间中访问.

  • 还应注意,第二种情况需要堆分配的字符串,如果您仅在堆栈创建的变量上使用寻址运算符,则会遇到与第一种情况相同的问题。 (2认同)
  • @sohum 指针指向数据的地址位置,引用指向数据。这些不是一回事,因为当与 &amp; 符一起使用时,它们都指向数据位置? (2认同)

gav*_*inb 5

您的函数声明了对字符串的常量引用

int foo(const string &myname) {
  cout << "called foo for: " << myname << endl;
  return 0;
}
Run Code Online (Sandbox Code Playgroud)

引用有一些特殊的属性,这使得它在很多方面都比指针更安全:

  • 它永远不能为 NULL
  • 它必须始终被初始化
  • 一旦设置,就不能更改为引用不同的变量
  • 它可以以与它所引用的变量完全相同的方式使用(这意味着您不需要像指针一样尊重它)

函数签名与等效的 C 有何不同:

int foo(const char *myname)
Run Code Online (Sandbox Code Playgroud)

有几个区别,因为第一个直接const char*引用一个对象,而必须取消引用才能指向数据。

使用字符串 *myname 与字符串 &myname 之间有区别吗?

处理参数时的主要区别在于您不需要取消引用&myname。一个更简单的例子是:

int add_ptr(int *x, int* y)
{
    return *x + *y;
}
int add_ref(int &x, int &y)
{
    return x + y;
}
Run Code Online (Sandbox Code Playgroud)

做完全一样的事情。在这种情况下唯一的区别是您不需要取消引用xy因为它们直接引用传入的变量。

const string &GetMethodName() { ... }
Run Code Online (Sandbox Code Playgroud)

& 在这里做什么?是否有一些网站解释了 & 在 C 与 C++ 中的使用方式不同?

这将返回对字符串的常量引用。因此调用者可以直接访问返回的变量,但仅限于只读。这有时用于在不分配额外内存的情况下返回字符串数据成员。

引用有一些微妙之处 - 请查看有关引用C++ 常见问题解答以获取更多详细信息。