参数前的const与函数名后的const c ++


86

这样的东西有什么区别

friend Circle copy(const Circle &);

像这样

friend Circle copy(Circle&) const;

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


6
您将不会更改参数的其他参数
乍得2013年

Answers:


194

第一种形式意味着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;
};

11
Helluva回答!谢谢!
SexyBeast

1
那么,对于第二种情况,如果我有一个classconst对象,并且我调用like ,那应该发生什么,为什么?由于在调用方中已声明,因此应该不会失败?objXbar()obj.bar(obj)obj._x = 42objconst
SexyBeast

1
如果使后一个bar函数(void bar(X const& obj) {...})看起来像这样,该怎么办?void bar(const X& obj) {...},将const关键字移到该位置会发生什么变化吗?如果是这样,您也可以添加此示例吗?
加布里埃尔·斯台普斯

1
@GabrielStaples他们是一样的。const适用于其左侧的内容,或适用于左侧无内容的右侧的内容。在您的情况下,您会看到两种版本const都适用于X
AndreasFlöjt'17

69

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对象上调用该方法,并且该方法无法修改对其进行调用的对象(至少不是通过常规通道)。


2
完全正确,但是它不能回答问题,实际上不是在指类方法,而是朋友函数。
2013年

5
是的,我选择忽略该friend部分,因为我认为它实际上与OP的实际问题无关(否则,一旦所有问题暴露出来,真正的问题将变成什么)。就这样吧。
John Zwinck

我认为说“您可以在类类型的const对象上调用方法”有点误导,因为您可以在const对象或非const对象上调用const方法,而非const函数只能由非const对象调用。否则,这是我最喜欢的答案
csguy

8
Circle copy(Circle&) const;

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

成为成员函数const意味着

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

现在考虑下一个:

Circle copy(const Circle &);

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

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


7

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


const来自常量,表示某些内容不可更改,但可读性强。

  1. 如果我们使用const关键字限定变量,则以后将无法更改。
    例如,const变量必须在声明时进行初始化。
    constint var =25;
    var =50; // gives error

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

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

    *ptr=5445; //allowed

  3. 如果在之前用限定指针变量的话,我们可以改变指针本身,但是指针的内容是不能改变的。 例如 //但是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
                       }
           }; 

4

一个引用参数,另一个引用函数。

Circle copy(const Circle &);

这意味着传入的参数无法在函数中更改

Circle copy(Circle&) const;

const合格功能用于成员函数和方法不能更改对象本身的数据成员。您发布的示例是荒谬的。

从右到左阅读

如果我们将第一个函数重写为Circle copy(Circle const&);,这意味着相同的意思,那么从右到左阅读将变得很有用。copy是,需要一个函数const到参考Circle对象,并返回一个Circle通过引用对象。


0

friend Circle copy(const Circle &);//引用函数的常量参数。无法更改参数存储的值。

需要在您的示例中删除朋友 Circle copy(Circle&)const; //无法更改名为常量成员函数的此Poniter值


-1
friend Circle copy(const Circle &);

在函数调用期间,参数的值将不会更改。

friend Circle copy(const Circle &)const ; 

该函数是不更改类成员任何值的访问器。通常,功能类型为:访问器和更改器。访问器:检查但不更改其对象的状态。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.