我是C ++的初学者,这必须是一个非常基本的问题。我理解&代表参考操作。例如,a =& b将b的地址分配给a。然而,&在如下的声明中?
className& operator=(const className&);
以下是否有意义,最后一行与以下内容有何区别?
className* operator=(const className*);
从下面的答案中,似乎 - 据我所知 - 以下也是有效的。是吗?如果是,它与"&"?
的版本有什么不同className operator=(const className);
在阅读了下面的答案以及更多的答案后,我意识到我最初的混淆部分源于混淆了reference as in general computer science和reference type as in C++。谢谢所有回答我问题的人。所有的答案都在不同程度上澄清了我的理解,尽管我只能选择一个作为公认的答案。
答案 0 :(得分:3)
令牌&
在C ++中有三个不同的含义,其中两个是从C继承的,其中一个不是。
a = &b
。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;是多态的。