【问题标题】:const before parameter vs const after function name c++参数前的 const 与函数名后的 const C++
【发布时间】:2013-04-06 14:52:15
【问题描述】:

这样的东西有什么区别

friend Circle copy(const Circle &);

类似的东西

friend Circle copy(Circle&) const;

在函数用于告诉编译器该函数不会尝试更改它所调用的对象后,我知道 const,那么另一个呢?

【问题讨论】:

  • 你不会改变参数是另一个

标签: c++ function constants


【解决方案1】:

第一种形式意味着绑定到引用的Circle 对象的(状态)是copy() 函数的参数,copy() 不会通过该引用更改该引用。该引用是对const 的引用,因此无法通过该引用调用Circle 的成员函数,这些函数本身不符合const 的条件。

另一方面,第二种形式是非法的:只有 成员函数 可以是 const-qualified(而您声明的是全局 friend 函数)。

const 限定成员函数时,限定指的是隐含的this 参数。换句话说,不允许该函数更改调用它的对象的状态(隐式this 指针指向的对象)- mutable 对象除外,但这是另一回事。

用代码说:

struct X
{
    void foo() const // <== The implicit "this" pointer is const-qualified!
    {
        _x = 42; // ERROR! The "this" pointer is implicitly const
        _y = 42; // OK (_y is mutable)
    }

    void bar(X& obj) const // <== The implicit "this" pointer is const-qualified!
    {
        obj._x = 42; // OK! obj is a reference to non-const
        _x = 42; // ERROR! The "this" pointer is implicitly const
    }

    void bar(X const& obj) // <== The implicit "this" pointer is NOT const-qualified!
    {
        obj._x = 42; // ERROR! obj is a reference to const
        obj._y = 42; // OK! obj is a reference to const, but _y is mutable
        _x = 42; // OK! The "this" pointer is implicitly non-const
    }

    int _x;
    mutable int _y;
};

【讨论】:

  • 地狱回答!谢谢!
  • 所以,对于第二种情况,如果我有一个 objXconst 对象,并且我像 obj.bar(obj) 一样调用 bar(),应该发生什么以及为什么? obj._x = 42 不应该失败吗,因为 obj 在调用者中被声明为 const
  • 如果你让后一个条形函数(void bar(X const&amp; obj) {...})看起来像这样呢? void bar(const X&amp; obj) {...},将 const 关键字移动到这个位置会改变什么吗?如果是这样,你也可以添加这个例子吗?
  • @GabrielStaples 他们是一样的; const 适用于左侧的内容,或右侧的内容,以防左侧没有任何内容。在您的情况下,您会看到两个版本的const 都应用于X
  • 很好的答案,通俗易懂
【解决方案2】:

C++ 类方法有一个隐含的this 参数,它位于所有显式方法之前。所以在一个类中声明的函数是这样的:

class C {
  void f(int x);

你可以想象真的是这样的:

  void f(C* this, int x);

现在,如果你这样声明:

  void f(int x) const;

好像是你写的:

  void f(const C* this, int x);

也就是说,尾随的const 使this 参数变为const,这意味着您可以在类类型的const 对象上调用该方法,并且该方法不能修改调用它的对象(至少,而不是通过正常渠道)。

【讨论】:

  • 完全正确,但它没有回答问题,这实际上不是指类方法,而是指朋友函数。
  • 是的,我选择忽略 friend 部分,因为我认为它实际上与 OP 的真正问题无关(或者一旦所有问题都暴露出来,真正的问题会变成什么)。就这样吧。
  • 我认为说“你可以在类类型的 const 对象上调用方法”有点误导,因为你可以在 const 对象或非 const 对象上调用 const 方法,而非 const 函数只能由非常量对象调用。否则这是我最喜欢的答案
【解决方案3】:

让我们清除与 const

相关的所有困惑

const 来自 constant 表示某些东西不可更改但可读。

  1. 如果我们用 const 关键字来限定我们的变量,我们以后不能更改它。
    例如
    constint var =25; const 变量必须在声明时初始化。
    var =50; // gives error

  2. 如果我们用 const * 来限定我们的指针变量,那么我们不能更改指针本身,但指针的内容是可更改的
    例如
    int *const ptr = new int;
    ptr = new int; //gives error
    // 但是
    *ptr=5445; //allowed

  3. 如果我们用 const before * 来限定我们的指针变量,那么我们 可以 更改指针本身,但指针的内容不可更改
    例如
    intconst* ptr = new int(85);
    //or
    constint * ptr = new int(85);
    ptr = new int; // allowed
    // 但是
    *ptr=5445; // gives error

  4. 指针和内容都是常量
    例如
    intconst*constptr = new int(85);
    //or
    const strong>int *constptr = new int(85);
    ptr = new int; // not allowed
    *ptr=5445; // not allowed


  1. Circle copy(const Circle &amp;);
    这里 const Circle 表示 Circle 的值是只读的,如果我们尝试在函数内部更改 Circle 的值,则会出错。
  2. friend Circle copy(Circle&amp;) const;
    这种类型的函数不适用于非成员变量。它用于类或结构。 这里整个函数用 const 关键字限定意味着我们不能改变 object member variable 。 例如
    class A{ public :
              int  var;
              void fun1()
                    { var = 50; // allowed
                    } 
              void fun2()const
                       { var=50; //not allowed
                       }
           }; 

【讨论】:

    【解决方案4】:
    Circle copy(Circle&) const;
    

    使函数 const 自己。这只能用于类/结构的成员函数。

    制作成员函数const意味着

    • 不能调用任何非常量成员函数
    • 不能改变任何成员变量。
    • 可以被const对象调用(const对象只能调用const函数)。非常量对象也可以调用 const 函数。
    • 必须是“Circle”类的成员函数。

    现在考虑下一个:

    Circle copy(const Circle &);
    

    而这意味着传递的参数不能在函数内更改。它可能是也可能不是类的成员函数。

    注意:可以以这样的方式重载一个函数,以使同一函数具有const 和非常量版本。

    【讨论】:

      【解决方案5】:

      一个指向参数,另一个指向函数。

      Circle copy(const Circle &);
      

      这意味着传入的参数不能在函数内改变

      Circle copy(Circle&) const;
      

      const 限定函数用于成员函数,意味着您不能更改对象本身的数据成员。您发布的示例是荒谬的。

      从右到左阅读

      如果我们将第一个函数重写为Circle copy(Circle const&amp;);,这意味着同样的事情,很明显从右到左读取变得有用。 copy 是一个函数,它接受 constCircle 对象的引用并通过引用返回 Circle 对象。

      【讨论】:

        【解决方案6】:

        friend Circle copy(const Circle &amp;);//指函数的常量参数。 can't'改变参数存储的值。

        在您的示例中需要删除朋友 圆复制(Circle&) const; //不能改变这个命名为常量成员函数的指针值

        【讨论】:

          【解决方案7】:
          friend Circle copy(const Circle &);
          

          在函数调用期间参数的值不会改变。

          friend Circle copy(const Circle &)const ; 
          

          该函数是一个不会改变任何类成员值的访问器。通常,函数有多种类型:访问器和修改器。 Accessor:检查但不改变其对象的状态。

          【讨论】:

            猜你喜欢
            • 2010-09-14
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 2023-03-20
            • 2012-02-25
            • 2021-12-23
            • 1970-01-01
            相关资源
            最近更新 更多