关于 const 成员函数

发布于 2024-08-16 20:57:07 字数 220 浏览 7 评论 0原文

我遇到了 const 成员函数的两种解释,

class A{
  public:
  ...
  void f() const {}
  ...
}
  1. 这意味着它只能访问常量成员;
  2. 这意味着它不会修改任何成员;

我认为第二个是对的。但为什么会出现第一个呢?有什么需要澄清的吗?

谢谢!

I met two explanation of const member function

class A{
  public:
  ...
  void f() const {}
  ...
}
  1. it means it could only access constant members;
  2. it means it does not modify any members;

I think the second one is right. But why does the first one come out? Is there anything to be clarify?

Thanks!

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

自找没趣 2024-08-23 20:57:08

您可以检查 const 成员函数中的所有类成员值,在某些情况下甚至可以更改成员变量的值。第一个解释是错误的,我不知道它来自哪里。第二种解释是正确的,但也有一些例外。

此规则有一些例外。您还可以更改 const 成员函数中的可变变量,例如这样声明的成员变量:

mutable float my_rank;

您还可以通过 const_cast'ing 对自己的引用来破坏类中的 const 正确性,如下所示:

Class* self = const_cast<Class*> (this);

虽然在 C++ 中技术上允许,但这是通常被认为是糟糕的形式,因为它抛弃了设计中的所有 const 修饰符。除非确实必须这样做,否则不要这样做,并且如果您发现自己必须经常这样做,则表明您的设计存在问题。 C++ FAQ 很好地涵盖了这一点。

如果您想进行更多阅读,这里有两个参考:

You can examine all class member values in a const member function, and in some cases you can even change the value of member variables. The first explanation is incorrect, I don't know where it comes from. The second explanation is correct, but with a few exceptions.

There are some exceptions to this rule. You can also change mutable variables in a const member function, for example a member variable declared like this:

mutable float my_rank;

You can also break const-correctness in a class by const_cast'ing a reference to yourself like this:

Class* self = const_cast<Class*> (this);

While technically allowed in C++, this is usually considered poor form because it throws away all of the const modifiers of your design. Don't do this unless you actually have to, and if you find yourself having to do this quite a lot that suggests a problem with your design. The C++ FAQ covers this very well.

Here are two references in case you want to do more reading:

淡紫姑娘! 2024-08-23 20:57:08

简单来说,在 const 函数中你不能改变对象的状态。

在 const 函数中,该指针的行为类似于指向 const 数据的 const 指针,而在非 const 函数中,它的行为类似于指向 const 数据的 const 指针数据。

void foo() const  --> const ClassName * const this (so you can't alter data)

void foo() --> ClassName * const this (so you can alter data)

就 const 数据成员而言,您可以从任何成员函数访问(读取)它,无论其是否为 const。

正如詹姆斯·汤普森(James Thompson)所展示的,如果你愿意的话,你甚至可以通过删除常量来改变对象的状态。

class Bar
{
    int bar;
    public:
     void foo() const
     {
        this->bar = 0; //flashes error 

        Bar * const thisClass = const_cast<Bar * const>(this);
        thisClass->bar = 0;  
     }
};

可变数据成员也可以在 const 函数中更改。

In a simple meaning , in const function you can't change the state of the object.

In const function this pointer behaves as const pointer to const data , where as in non-const function it behaves like const pointer to data.

void foo() const  --> const ClassName * const this (so you can't alter data)

void foo() --> ClassName * const this (so you can alter data)

As far as const data member is concern , you can access (read ) it from any member function whether its const or not.

As James Thompson has shown you can even change state of object by removing constness if you want like this.

class Bar
{
    int bar;
    public:
     void foo() const
     {
        this->bar = 0; //flashes error 

        Bar * const thisClass = const_cast<Bar * const>(this);
        thisClass->bar = 0;  
     }
};

Also Mutable data members can be changed in const function.

梦明 2024-08-23 20:57:08

他们都是正确的。

const 成员函数不能改变对象的状态

  • 这意味着它可以读取(但不能修改)所有成员变量。
  • 这也意味着它只能调用其他 const 成员函数
    其他保证不改变对象状态的方法。

上面 James 还提到了可变成员。
所以我也应该在这里介绍这些。

可变成员变量是不属于对象状态的变量(编译器不认为它是对象状态的一部分)。你也应该这样对待。任何保存对象状态信息的成员变量都不应该被标记为可变的。您应该只使用它来保存可以从对象状态重建的临时信息。

一个简单的例子是日期时间对象。其中该对象具有将数据/时间转换为可读字符串格式的方法。为了提高效率,该字符串可能会缓存在对象的可变成员中(这样您就不需要重复构建该字符串)。但字符串不是对象状态的一部分(因为它可以从其他成员构建)。

James 还提到了上面使用 const_cast 抛弃常量性。

除非在非常特殊的情况下,你知道对象永远不可能常量,这样做通常被认为是一个坏主意。因为它直接导致未定义的行为。如果您发现自己需要放弃常量,那么您的程序中就发生了设计中的非常错误的事情。

事实上我只能想到一种正常发生的情况。然后,在没有先进行研究以确保我看起来不傻的情况下,我不愿意将其提交给代码。

They are both correct.

A const member function can not alter the state of the object.

  • This means it can read (but not modify) all member variables.
  • This also means it can only call other const member functions
    Other methods that guarantee not to change the state of the object.

Above James also mentions mutable members.
So I should also cover those here.

A mutable member variable is a variable that is not part of the state of the object (the compiler does not consider it part of the objects state). You should also treat it this way. Any member variable that holds state information about the object should NOT be marked mutable. You should only use it to hold temporary information that can be re-constructed from the objects state.

A simple example is a date-time object. Where the object has a method that converts the data/time into a readable string format. This string may be cached in the object in a mutable member for efficiency (so that you don't need to repeatedly build the string). But the string is not part of the object state (because it can be built from other members).

Also James mentions above casting away constness using const_cast.

Except under very special situations where you know the object CAN NEVER BE const doing this is considered universally a bad idea. As it leads directly to undefined behavior. If you find yourself needing to cast away constness then something very wrong in the design has happened in your program.

In fact I can only think of one situation where it happens normally. And then I am unwilling to commit it to code without first going and doing research to make sure I don't look silly.

夏末 2024-08-23 20:57:08

我认为经过一些澄清后,情况 1 可能涉及当您有一个 A 类型的 const 对象时的情况。在这种情况下,您只能调用其声明为 const 的成员函数,如本例中的 f() 。因此,根据您的帖子,您必须假设“it”是 const A 类型的对象上的成员函数的调用者。也许您应该回顾一下您发现的定义,并牢记这一假设。

I think the case 1 after some clarification may concern the situation when you have a const object of type A. In such a case you can only call its member functions declared as const like f() in this case. So according to your post you must assume that 'it' is the caller of the member functions on an object of type const A. Maybe you should review the definition you found having in mind this assumption.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文