返回引用的 Const 方法
class Foo
{
int Bar;
public:
int& GetBar() const
{
return Bar;
}
}
GetBar
是一个 const
方法可以吗?它实际上并没有改变任何东西,但它为“外部世界”提供了改变它的手段。
class Foo
{
int Bar;
public:
int& GetBar() const
{
return Bar;
}
}
Is it okay that GetBar
is a const
method? It's not actually changing anything, but it's providing the "outside world" with a means of changing it.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(6)
不,这是不合法的。当使用
const
标记方法时,您不仅承诺不会触及对象的任何内部状态,还承诺不会返回任何可用于更改状态的内容的对象。非常量引用可用于在GetBar()
范围之外修改 Bar 的值,因此您暗示您无法兑现承诺。您必须将该方法更改为非常量,返回常量引用,或者通过将其标记为可变来使
Bar
免除承诺。例如:mutable int Bar;
mutable
关键字告诉编译器该对象的逻辑常量不依赖于Bar
的状态。然后你就可以用它做任何你想做的事。No, this is not legal. When tagging a method with
const
, not only are you promising you won't touch any of the internal state of the object, you also promise that you will not return anything that can be used to change the state of the object. A non-const reference may be used to modify the value of Bar outside the scope ofGetBar()
, hence you are implying that you cannot hold the promise.You must either change the method to being non-const, return a const reference, or make
Bar
exempt of the promise by marking it asmutable
. E.g.:mutable int Bar;
Themutable
keyword tells the compiler that the logical constness of the object does not depend on the state ofBar
. Then you are allowed to do whatever you please with it.不,因为你不能做以下作业:
常量 int x; int &y = x;
你可以做的是
const int x; const int &y = x;
当然,重载该方法并创建 const 和非 const 变体是没有问题的。
Nope, since you cant do the following assignment:
const int x; int &y = x;
What you can do though is
const int x; const int &y = x;
And of course there is no problem in overloading the method and creating both const and non-const variants.
不,你不能那样做;在
const
方法中,您有一个const
this
指针(在您的情况下,它将是一个const Foo *
) ,这意味着您可以获取其字段1 的任何引用都将是const
引用,因为您是通过“const
”访问它们小路”。因此,如果您尝试执行在该代码中所做的操作,您将收到编译错误,因为您将尝试使用以下代码初始化
int &
(方法的返回值)const int &
(从Bar
获得的引用),这显然是被禁止的。g++实际上说:
这就是我刚才所说的。
:)
相反,如果您从
const
方法返回对类字段的const
引用,则不会有任何问题。mutable
的字段,它告诉编译器这些字段甚至可以通过const
方法进行修改;引入此异常是为了允许 const 方法在不改变其“逻辑”状态的情况下更改对象的“真实”状态;这对于实现惰性求值、引用计数等很有用。No, you can't do that; in a
const
method you have aconst
this
pointer (in your case it would be aconst Foo *
), which means that any reference you can get to its fields1 will be aconst
reference, since you're accessing them through a "const
path".Thus, if you try to do what you did in that code you'll get a compilation error, since you'd be trying to initialize an
int &
(the return value of your method) with aconst int &
(the reference you get fromBar
), which obviously is forbidden.g++ actually says:
which is what I just said.
:)
If, instead, you return a
const
reference to a class field from aconst
method you'll have no problem.mutable
, which tells to the compiler that such fields are modifiable even fromconst
methods; this exception has been introduced to allowconst
methods to change the "real" state of the object in cases when this do not alter its "logical" state; this can be useful to implement lazy evaluation, reference counting, ...您可能想要返回
Bar
,而不是&Bar
。无论如何,我在 Comeau 中删除了这段代码:并得到了错误:
You probably want to return
Bar
, not&Bar
. Anyway, I dropped this code in Comeau:And got the error:
当您使用 const 方法时,类的成员被视为 const。因此,虽然
Bar
在类中是int
而不是const int
,但在GetBar() const
的上下文中它是“const int”。因此,将其作为非常量引用或指针返回与执行以下操作一样非法:const int y = 57;
整数& z = y;
即使第二行实际上还没有改变 y 中的任何内容,这也会破坏常量正确性。
顺便注意一下,如果你的类有指针成员,那么唯一的 const 就是指针本身,而不是它们指向的内容。 (通常称为“浅”常量)
因此这是合法的:
请注意,在原始代码中,如果
可变
,您将被允许通过非常量引用返回Bar
code>,因为这些成员不受成员函数常量的约束。The members of your class are considered const when you are in a const method. So although
Bar
isint
within your class and notconst int
, in the context ofGetBar() const
it is "const int". Therefore returning it as a non-const reference or pointer is just as illegal as doing:const int y = 57;
int& z = y;
This breaks const-correctness even though the 2nd line has not actually changed anything (yet) in y.
Note incidentally that if your class has pointer members the only thing that is const is the pointers themselves and not what they point to. (Often referred to as "shallow" constness)
Thus this would be legal:
Note that in your original code you would be allowed to return
Bar
by non-const reference if it weremutable
, because those members are not bound by the constness of member functions.成员函数的 const 修饰符不允许在其作用域内更改对象的状态。编译器只是检查该函数是否在其作用域内修改对象的状态。再举一个例子 -
因此,编译器只检查访问说明符(即,该变量在此范围内是否可访问),而不检查私有/公共/受保护变量的内存位置(如果返回到其他变量)。
const
modifier to a member function doesn't allow to change the object's state with in it's scope. Compiler just checks whether this function is modifying the state of the object or not in its scope. Taking another example -So, compiler just checks access specifiers ( i.e., whether this variable is accessible or not in this scope) but not about the private/public/protected variable's memory location if returned to some other variable.