C ++在声明中引用运算符

时间:2014-03-14 05:30:28

标签: c++ reference

我是C ++的初学者,这必须是一个非常基本的问题。我理解&代表参考操作。例如,a =& b将b的地址分配给a。然而,&在如下的声明中?

className& operator=(const className&);

以下是否有意义,最后一行与以下内容有何区别?

className* operator=(const className*);

从下面的答案中,似乎 - 据我所知 - 以下也是有效的。是吗?如果是,它与"&"?

的版本有什么不同
className operator=(const className);

在阅读了下面的答案以及更多的答案后,我意识到我最初的混淆部分源于混淆了reference as in general computer sciencereference type as in C++。谢谢所有回答我问题的人。所有的答案都在不同程度上澄清了我的理解,尽管我只能选择一个作为公认的答案。

4 个答案:

答案 0 :(得分:3)

令牌&在C ++中有三个不同的含义,其中两个是从C继承的,其中一个不是。

  1. 它是按位AND运算符(除非过载)。
  2. 它是地址运算符,它作用于左值以产生指向它的指针。 (除非超载。)这就是a = &b
  3. 中发生的事情
  4. 表示参考类型const className&作为参数是对const类型的对象的className 引用,因此当调用该函数时,参数将通过引用传递,但是它不会被函数修改。您提供的功能也会返回参考。

答案 1 :(得分:2)

分配操作员

最好通过示例获得理解:

class A {
  int x;
public:
  A(int value) : x(value) {}
  A& operator=(const A& from) {     // Edit: added missing '=' in 'operator='
    x = from.x;
    return *this;
  }
};

A m1(7);
A m2(9);
m2 = m1;   /// <--- calls the function above, replaces m2.x with 7

在这里,我们定义了赋值运算符。这种特殊方法旨在为对象提供赋值功能。

它返回对* this的引用的原因是你可以在没有过多内存副本的情况下链接赋值:

A m3(11);
m3 = m1 = m2;   /// <--- now, m3.x and m1.x both set to m2.x

扩展如下:

  m3 = ( something ) 
where
  (something) is a reference to the object m1 
  by result of call to m1.operator=(m2) method
such that
  the returned reference is then passed into m3.operator(...)

Chaining让你这样做:

(m1=m2).function(); // calls m1.function after calling assignment operator

boost这样的库利用了这种模式(对于不同类型的链接示例,请参阅boost中的程序选项库),在开发特定于域的“语言”时它非常有用。

如果从operator =返回完整对象,则链接赋值至少涉及对象的多个额外副本,浪费CPU周期和内存。在许多情况下,由于副本,事情无法正常工作。

基本上,使用引用可以避免复制。

注意

实际上,(简化说明)引用只是C指针的奇特语法。 在常见情况下,您可以使用A.x而不是A-&gt; x来编写代码。

注意

从方法中返回纯引用通常很危险; newcomers可以尝试返回对堆栈中方法内部构造的对象的引用,这取决于对象可能导致隐藏的错误。

您的指针示例

这取决于您从方法体返回的内容,但无论如何,以下内容将返回指向className的某个实例的指针:

className* operator=(const className*);

这将编译,它甚至似乎工作(如果你从方法中返回),但这确实违反了Rule of Least Surprise,因为很可能其他人试图使用你的代码不会指望赋值运算符返回指针。

如果你考虑基类型:

int x=1; int y=2; int z; z=y=x;
除了返回整数之外,

永远不会做任何事情 - 所以让operator =返回分配给对象是一致的)

它也不允许你这样做:

(m1 = m2).something

它还允许您传递NULL,这是赋值运算符通常不想关注的东西。

而不是写

blah& operator(const blah& x) { a = x.a ; return *this; }

你需要写:

blah* operator(const blah* x) { 
  if (x) { a = x->a ; return this; }
  else { /*handle null pointer*/
} 

答案 2 :(得分:1)

这意味着该函数会引用const className并返回对className的引用

假设您有类似下面的课程:

class className
{
   public:
      className& operator=(const className& rhs)
      {
         this->a_ = rhs.a_;
         this->b_ = rhs.b_;
         return *this;
      }

   private:
      std::string a_;
      std::string b_;
};

您可以使用该类的赋值运算符,如下所示:

className a;
className b;
className c;

c = b = a;

上述行执行如下:

c.operator=(b.operator=(a));

现在使用另一个使用第二种形式定义operator=的类:

class className2
{
   public:
      className2* operator=(const className2* rhs)
      {
         this->a_ = rhs->a_;
         this->b_ = rhs->b_;
         return this;
      }

   private:
      std::string a_;
      std::string b_;
};

您可以使用该类的赋值运算符,如下所示:

className2 obj1;
className2 obj2;
className2 obj3;

obj2 = &obj1;
obj3 = &obj2;

上述行执行如下:

obj2.operator=(&obj1);
obj3.operator=(&obj2);

然而,这种编码并不直观。您没有指定对象的指针。更直观地说:

className obj1;
className* objPtr = NULL;

objPtr = &obj1;

答案 3 :(得分:-1)

a = &b

此处,&给出地址b。

className& operator=(const className&);

这里,operator =将获取类型为className的变量的const引用。

你可以用C ++,&amp;是多态的。