在函数名c ++之后的参数vs const之前的const

jaz*_*azz 63 c++ const function

这样的事情之间有什么区别

friend Circle copy(const Circle &);
Run Code Online (Sandbox Code Playgroud)

和这样的事情

friend Circle copy(Circle&) const;
Run Code Online (Sandbox Code Playgroud)

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

And*_*owl 162

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

另一方面,第二种形式是非法的:只有成员函数可以被const限定(而你宣称有一个全局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;
};
Run Code Online (Sandbox Code Playgroud)

  • Helluva回答!谢谢! (9认同)

Joh*_*nck 52

C++类方法有一个隐含this参数,它出现在所有显式参数之前.所以在类中声明的函数如下:

class C {
  void f(int x);
Run Code Online (Sandbox Code Playgroud)

你可以想象看起来真的像这样:

  void f(C* this, int x);
Run Code Online (Sandbox Code Playgroud)

现在,如果你这样声明:

  void f(int x) const;
Run Code Online (Sandbox Code Playgroud)

就像你写的那样:

  void f(const C* this, int x);
Run Code Online (Sandbox Code Playgroud)

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

  • 是的,我选择忽略"朋友"部分,因为我认为它实际上与OP的真实问题无关(或者一旦所有问题都暴露出来,真正的问题会变成什么样).就这样吧. (5认同)
  • 完全正确,但它没有回答问题,它实际上不是指类方法,而是指友元函数。 (2认同)

Ram*_*ary 10


让我们清除所有相关的混淆 const


const来自常量意味着某些东西是不可改变的但可读的。

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

  2. 如果我们用after限定我们的指针变量,那么我们不能改变指针本身,但指针的内容是可变的。 例如 // 但是const *

    int *const ptr = new int;
    ptr = new int; //gives error

    *ptr=5445; //allowed

  3. 如果我们使用before限定我们的指针变量,那么我们可以更改指针本身,但指针的内容是不可更改的。 例如 // 但是const *

    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
    constint *constptr = new int(85);
    ptr = new int; // not allowed
    *ptr=5445; // not allowed


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


Waq*_*med 6

Circle copy(Circle&) const;
Run Code Online (Sandbox Code Playgroud)

使功能const本身。这只能用于类/结构的成员函数。

成为成员函数const意味着

  • 它不能调用任何非const成员函数
  • 它不能更改任何成员变量。
  • 可以由const对象const调用(对象只能调用const函数)。非常量对象也可以调用const函数。

这个必须是“ Circle ” 类的成员函数。

现在考虑下一个:

Circle copy(const Circle &);
Run Code Online (Sandbox Code Playgroud)

而这意味着不能在函数中更改传递的参数。这个可能是该类的成员函数,也可能不是。

注意:可以以具有const相同功能的非常量版本的方式重载功能。


Ale*_*ain 5

一个指的是参数,另一个指的是函数。

Circle copy(const Circle &);
Run Code Online (Sandbox Code Playgroud)

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

Circle copy(Circle&) const;
Run Code Online (Sandbox Code Playgroud)

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

从右到左阅读

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