【问题标题】:C++ "const" keyword explanationC++“const”关键字解释
【发布时间】:2010-10-31 17:50:55
【问题描述】:

在阅读用 C++ 编写的教程和代码时,我经常会偶然发现 const 关键字。

我看到它是这样使用的:

const int x = 5;

我知道这意味着x 是一个常量变量,可能存储在只读内存中。

但是什么是

void myfunc( const char x );

int myfunc( ) const;

?

【问题讨论】:

标签: c++ constants


【解决方案1】:
void myfunc(const char x);

这意味着参数x 是一个char,其值不能在函数内部更改。例如:

void myfunc(const char x)
{
  char y = x;  // OK
  x = y;       // failure - x is `const`
}

最后一个:

int myfunc() const;

这是非法的,除非它在类声明中 - const 成员函数阻止修改任何类成员 - const 不能使用非成员函数。在这种情况下,定义类似于:

int myclass::myfunc() const
{
  // do stuff that leaves members unchanged
}

如果您有特定的类成员需要在const 成员函数中进行修改,您可以将它们声明为mutable。例如,成员 lock_guard 使类的 const 和非 const 成员函数线程安全,但必须在其自身的内部操作期间进行更改。

【讨论】:

  • 重点不是启用 const 方法,而是能够调用 const 对象上的任何方法......所以可变成员不是可以更改的成员一个 const 方法,它更像是一个允许在其他 const 对象上更改的成员。
  • @ufotds - 正确 - 不要因为对成员函数上的 const 含义的误解而无法编译您的代码。
【解决方案2】:

第一个函数示例或多或少毫无意义。更有趣的是:

void myfunc( const char *x );

这告诉编译器*x内容 不会被修改。也就是说,在 myfunc() 内,您不能执行以下操作:

strcpy(x, "foo");

第二个例子,在 C++ 成员函数上,意味着对象的内容不会被调用改变。

所以给定:

class {
  int x;
  void myfunc() const;
}

someobj.myfunc() 不允许修改如下内容:

x = 3;

【讨论】:

  • 第一个示例实际上可以帮助编译器生成更优化的代码,尽管如果不修改变量,大多数现代编译器很可能会自行找出它们。
  • 第一个示例还可以防止意外修改。虽然从调用者的角度来看这无关紧要,但有时声明每个参数和局部变量 const 很有帮助,因为修改它们可能会导致错误或糟糕的设计。
  • 即使它毫无意义(一点也不,我同意@Philipp),你至少应该解释一下为什么。 (但是当你被告知这是错误的时候,不要再这样做了。)
【解决方案3】:

这个:

void myfunc( const char x );

表示您不能在函数内部更改x,即这是非法的:

void myfunc( const char x ) {
    x = ...;
}

同时:

int myfunc() const;

只有当 myfunc() 是类中的方法时才有意义;它基本上意味着该方法不能修改类实例(即调用 instance.myfunc() 之前和之后实例的状态将是相同的)。

【讨论】:

    【解决方案4】:

    在变量标识符之前,const 表示该变量可以被初始化并且此后不能被修改。

    在类方法名之后,const表示该方法不会修改类的可观察状态。 mutable 关键字允许修改内部数据。

    在指针或引用变量之前,const 表示该标识符不会用于修改引用的数据,但可以通过其他方式进行更改。

    const int *pInt = &x;
    

    也可以用const来表示指针本身不能修改:

    int * const pInt = &x;
    

    【讨论】:

      【解决方案5】:

      我在http://duramecho.com/ComputerInformation/WhyHowCppConst.html找到了一个很好的解释

      基本上所有的混淆都在于关键字const 的不同用例。根据您放置const 的位置,您会告诉您某些东西应该是不可变的,或者某些东西不应该能够改变其他东西。 'something' 可能是变量或指针或函数/方法,您不希望它能够更改传递给对象的函数或成员变量的变量的值。

      【讨论】:

      • 这只是 Google 热门搜索结果。
      【解决方案6】:

      void myfunc(const char x) 与您的示例中的const int x = 5 非常相似:它在函数myfunc 中声明了一个本地可用的常量。因为它是一个常数,所以它的值不能改变。

      int myfunc() const 是类的成员函数。 const 表示该函数不会更改执行该函数的类的实例。因此,在函数内,您不能执行 this->foo = 7 之类的操作或调用其他非 const 函数。

      【讨论】:

        【解决方案7】:

        两者的区别在于第一个的类型为void(char),第二个的类型为int()const

        具有const这种类型的函数只能是类的成员函数,这意味着该成员函数不会改变类的值(this所指的)。从课外。编译器会在一定程度上检查这一点,任何直接写入 const 成员函数中的类成员都会导致编译时错误,并且该函数只能直接调用自身的 const 成员函数(存在特殊指令,因此您可以告诉成员编写的编译器不会改变从外部看到的类的值。这是由mutable 关键字完成的)。

        在您介绍的函数中,有一个类型为char const 的参数。这样的参数不能在其函数内部更改。但它对函数的类型没有影响,对函数的调用者也没有影响。

        【讨论】:

        • 虽然这些类型肯定是正确的,但对于新手来说,它们非常可能会胡言乱语。
        【解决方案8】:

        const 限定符意味着定义为 const 的变量/指针可能不会被您的程序更改,它将通过显式初始化或硬件相关方式接收其值。

        在参数声明中定义为const的指针,函数代码不会修改它所指向的内容。基本上,您可以使用指针,它几乎可以用作“只读”。

        例如:-

        void foo(const char *x)
        {
            while(*x)
            {
                if(*x==' ') cout << '-'; //printing - when a space is encountered
                else cout << *x;
                x++;
            }
        }
        

        上面的函数很好,不会显示任何错误。但是如果 foo 有任何东西可以改变传递的字符串。说一个用 $ 替换空格的函数。不打印 $ 而是将其更改为 $。像这样的东西:-

        void foo(const char *x)
        {
            while(*x)
            {
                if(*x==' ') *x = '$'; //printing - when a space is encountered
                else cout << *x;
                x++;
            }
        }
        

        然后它不会编译,即对只读内存位置的分配错误。

        【讨论】:

          【解决方案9】:

          接受的答案(以及我略读的其他答案)不正确。 不要假设“const”意味着标识符(如您的 x)“不能在函数内部更改”。这意味着无法直接更改标识符。但它很容易改变。

          考虑完整的程序(为新手编写):

          #include <iostream>
          
          void break_const(const int x) {
              const int* x_ptr = &x;
              std::intptr_t z = reinterpret_cast<std::intptr_t>(x_ptr);
              int* hacked = reinterpret_cast<int*>(z);
              *hacked = 3;
              std::cout << "x = " << x << std::endl;
          }
          
          int main() {
              break_const(5);
              return 0;
          }
          

          输出是“x = 3”。

          编辑:我还应该补充一点,我的声明“这意味着不能直接更改标识符”有点不对劲。对于整数,这很好。但对于更复杂的类型,const 意味着更少(例如,在类中是可变的)。

          【讨论】:

          • 但是你为什么要这样做呢?如果您想更改它,请不要将其声明为 const
          • @M. Kotzjan 我同意你的观点,你不应该这样做。问题是你可以做到这一点。所以像“这意味着参数 x 是一个字符,其值不能在函数内部更改”这样的陈述是错误的。
          猜你喜欢
          • 2023-03-05
          • 1970-01-01
          • 1970-01-01
          • 2021-09-14
          • 2010-11-27
          • 2022-01-05
          • 2010-12-06
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多