简体   繁体   English

为什么必须在运算符重载中提供关键字const

[英]why must you provide the keyword const in operator overloads

Just curious on why a param has to be a const in operation overloading 只是好奇为什么一个param必须是一个const操作重载

CVector& CVector::operator= (const CVector& param)
{
  x=param.x;
  y=param.y;
  return *this;
}

couldn't you have easily done something like this ?? 难道你不能轻易做到这样的事吗?

CVector& CVector::operator= (CVector& param) //no const
{
  x=param.x;
  y=param.y;
  return *this;
}

Isn't when something becomes a const, it is unchangeable for the remainder of the applications life ?? 当某些东西变成一个const时,它对于应用程序生命的其余部分是不可改变的? How does this differ in operation overloading ??? 这在操作重载方面有何不同?

You don't need const: 你不需要const:

@numerical25: Just curious on why a param has to be a const in operation overloading @ numerical25:好奇为什么一个param必须是一个const操作重载

It's not required, but it is a good design decision. 这不是必需的,但这是一个很好的设计决定。

See the C++ standard Section 12.8-9: 请参阅C ++标准第12.8-9节:

A user-declared copy assignment operator X::operator= is a non-static non-template member function of class X with exactly one parameter of type X, X&, const X&, volatile X& or const volatile X& 用户声明的复制赋值运算符X :: operator =是类X的非静态非模板成员函数,其中只有一个参数类型为X,X&,const X&,volatile X&或const volatile X&


I think it's a good idea though: 我认为这是一个好主意:

Using a const parameter does seems like a logical design decision to me though because you want to ensure that the other value will not be changed. 使用const参数对我来说似乎是一个逻辑设计决策,因为您希望确保不会更改其他值。

It tells other people that use your class that you will not be changing the other value when you say something like: myObject = other; 它告诉其他人使用你的类,当你说出类似的东西时,你不会改变other值: myObject = other; and it enforces this so you can't accidentally change other . 并强制执行此操作,以免意外更改other

Also if you allowed non const references to the object as the parameter, then you are limiting the amount of objects that can use your function. 此外,如果您允许对对象的非const引用作为参数,那么您将限制可以使用您的函数的对象数量。 If it is const it can be used for parameters that are const and non const. 如果它是const,它可以用于const和非const的参数。 If your parameter is non const it can only be used by parameters that are non const. 如果您的参数是非const,则它只能由非const的参数使用。


const only applies to the current reference, not the object: const仅适用于当前引用,而不是对象:

@numerical25: Isn't when something becomes a const, it is unchangeable for the remainder of the applications life ?? @ numerical25:当某些东西变成一个const时,它对于应用程序生命的其余部分是不可改变的? How does this differ in operation overloading ??? 这在操作重载方面有何不同?

A const reference is simply that a reference that is const. const引用只是一个const引用。 It does not change the const-ness of the actual object you are passing in. 它不会改变您传入的实际对象的常量。


An example of non-const operator overloading: 非const运算符重载的示例:

Here is an example of operator overloading where the parameter is not const. 以下是运算符重载的示例,其中参数不是const。
I DO NOT RECOMMEND TO DO THIS THOUGH: 我不建议做这件事:

class B
{
public: 
 const B& operator=(B& other)
 {
  other.x = 3;
  x = other.x;
  return *this;
 }

 int x;
};


void main(int argc, char** argv[])
{
 B a;
 a.x = 33;
 B b;
 b.x = 44;
 a = b;//both a and b will be changed
 return 0;
}

A const parameter is const throughout the function using it, it does not change its constness outside of it. const参数在使用它的整个函数中都是const,它不会在它之外改变它的常量。

In this case you want to declare a const argument so that your assignment operator accepts both non-const variables and const variables; 在这种情况下,您需要声明一个const参数,以便赋值运算符接受非const变量和const变量; the latter case, in particular, includes the result of expressions, which is a temporary const variable and which you generally want to support in assignments. 特别是后一种情况,包括表达式的结果,这是一个临时的const变量,你通常希望在赋值中支持它。

If you used 如果你用过

CVector& CVector::operator= (CVector& param) // no const

then did this: 然后做了这个:

const CVector& my_vector = GetMyVector();
some_other_vector = my_vector; // call assignment operator - error!

You'll get an error because my_vector is a const CVector& and that can't be cast to a CVector& (non-const reference). 你会得到一个错误,因为my_vector是一个const CVector&而且无法转换为CVector& (非const引用)。 It's just the local reference to it inside the operator= function that is const, not the entire object itself. 它只是在operator= function中的本地引用,它是const,而不是整个对象本身。

You can use the non-const variety, but this has two repercussions, one which is functional, and one which is about what you, as the writer of the function, are telling the user. 你可以使用非常数变种,但这有两个反响,一个是功能性的,另一个是关于你作为函数的作者告诉用户的内容。

1) people calling the function that takes a non-const reference would not be able to call it using a const variable 1)调用带有非const引用的函数的人将无法使用const变量调用它

2) when you have a function argument that's a non-const reference, you're signalling, "I reserver the right to change this". 2)当你有一个非const引用的函数参数时,你发出信号,“我保留了改变它的权利”。 Typically, when a user of your function writes a = b;, he doesn't expect b to change. 通常,当您的函数的用户写a = b;时,他不希望b更改。

Note that there's a third option you could use for this, pass-by-value: 请注意,您可以使用第三个选项,即按值传递:

CVector& CVector::operator= (CVector param) //no reference

This doesn't have either of the problems I mention above. 这没有我上面提到的任何问题。 However, it's very inefficient. 但是,效率非常低。 Because of these three factors, passing by reference-to-const is preferred, especially in cases like a vector where copying can be expensive. 由于这三个因素,通过引用到const是优选的,特别是在像复制可能很昂贵的向量的情况下。

出于同样的原因,你可以在任何地方使用const:确保将来对方法的更改不会无意中修改传入的参数,以帮助记录接口通知调用者传递param是安全的,而不会有更改的风险,并且允许调用者传入在调用代码中声明为const的引用。

Another reason is to allow for conversions. 另一个原因是允许转换。 For example: 例如:

string s = "foo";
s = "bar";

Here, an implementation might choose to only provide the assignment operator that takes a const reference to a string as a parameter, and depend on the compiler using a constructor to create a temporary string from the char * "bar". 这里,实现可能选择仅提供赋值运算符,该赋值运算符将对字符串的const引用作为参数,并依赖编译器使用构造函数从char *“bar”创建临时字符串。 This would not work if the op='s parameter was not const, as you cannot bind a temporary to a non-const reference. 如果op ='s参数不是const,这将无效,因为您无法将临时绑定到非const引用。

The const qualifier makes the passed parameter (in your example it is 'const CVector& param') as read only. const限定符使传递的参数(在您的示例中为'const CVector&param')为只读。 The const qualifier ensures that the parameter (param) is not altered inside the operator=() method. const限定符确保在operator =()方法中不更改参数(param)。

Without the const qualifier, the following is possible: 如果没有const限定符,可以使用以下内容:

CVector& CVector::operator= (CVector& param)
{
  x=param.x;
  y=param.y;

  param.x = 10; // some random value
  param.y = 100;

  return *this;
}

The above method alters the right hand side operand 'param' after assigning the value to the left hand side operand. 在将值赋给左侧操作数之后,上述方法改变右侧操作数'param'。 The const qualifier helps you not to violate the semantics of the assignment operation. const限定符可帮助您不违反赋值操作的语义。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM