your programing

클래스의 함수 선언에서 마지막 'const'의 의미는 무엇입니까?

lovepro 2020. 9. 30. 11:11
반응형

클래스의 함수 선언에서 마지막 'const'의 의미는 무엇입니까?


const이와 같은 선언에서 의 의미는 무엇입니까 ? const나를 혼란.

class foobar
{
  public:
     operator int () const;
     const char* foo() const;
};

const메서드에 키워드를 추가하면 this포인터는 기본적으로 const개체에 대한 포인터가 되므로 멤버 데이터를 변경할 수 없습니다. (사용하지 않는 한 mutable나중에 자세히 설명합니다).

const키워드는 두 개의 유사한 방법, 객체 인 경우라고 하나 구현할 수 있다는 것을 의미 기능 서명의 일부 const, 그리고 하나를.

#include <iostream>

class MyClass
{
private:
    int counter;
public:
    void Foo()
    { 
        std::cout << "Foo" << std::endl;    
    }

    void Foo() const
    {
        std::cout << "Foo const" << std::endl;
    }

};

int main()
{
    MyClass cc;
    const MyClass& ccc = cc;
    cc.Foo();
    ccc.Foo();
}

이것은 출력됩니다

Foo
Foo const

non-const 메서드에서는 const버전 에서 할 수없는 인스턴스 멤버를 변경할 수 있습니다 . 위 예제의 메서드 선언을 아래 코드로 변경하면 몇 가지 오류가 발생합니다.

    void Foo()
    {
        counter++; //this works
        std::cout << "Foo" << std::endl;    
    }

    void Foo() const
    {
        counter++; //this will not compile
        std::cout << "Foo const" << std::endl;
    }

멤버를로 표시 할 수 mutable있고 const메서드가이를 변경할 수 있기 때문에 이는 완전히 사실이 아닙니다 . 주로 내부 카운터와 물건에 사용됩니다. 이에 대한 해결책은 아래 코드입니다.

#include <iostream>

class MyClass
{
private:
    mutable int counter;
public:

    MyClass() : counter(0) {}

    void Foo()
    {
        counter++;
        std::cout << "Foo" << std::endl;    
    }

    void Foo() const
    {
        counter++;
        std::cout << "Foo const" << std::endl;
    }

    int GetInvocations() const
    {
        return counter;
    }
};

int main(void)
{
    MyClass cc;
    const MyClass& ccc = cc;
    cc.Foo();
    ccc.Foo();
    std::cout << "Foo has been invoked " << ccc.GetInvocations() << " times" << endl;
}

출력되는

Foo
Foo const
Foo has been invoked 2 times

const는 메서드가 클래스의 멤버를 변경하지 않을 것을 약속 함을 의미합니다. 그렇게 표시된 객체의 멤버는 객체 자체가 표시된 경우에도 실행할 수 있습니다 const.

const foobar fb;
fb.foo();

합법적입니다.

참조 얼마나 많은 및 C에서 "CONST"++의 사용은 있습니까? 자세한 내용은.


const규정 수단이 방법은 임의의 값으로 호출 될 수있다 foobar. 차이점은 const 객체에서 const가 아닌 메서드를 호출하는 것을 고려할 때 발생합니다. foobar유형에 다음과 같은 추가 메서드 선언이 있는지 고려하십시오 .

class foobar {
  ...
  const char* bar();
}

The method bar() is non-const and can only be accessed from non-const values.

void func1(const foobar& fb1, foobar& fb2) {
  const char* v1 = fb1.bar();  // won't compile
  const char* v2 = fb2.bar();  // works
}

The idea behind const though is to mark methods which will not alter the internal state of the class. This is a powerful concept but is not actually enforceable in C++. It's more of a promise than a guarantee. And one that is often broken and easily broken.

foobar& fbNonConst = const_cast<foobar&>(fb1);

These const mean that compiler will Error if the method 'with const' changes internal data.

class A
{
public:
    A():member_()
    {
    }

    int hashGetter() const
    {
        state_ = 1;
        return member_;
    }
    int goodGetter() const
    {
        return member_;
    }
    int getter() const
    {
        //member_ = 2; // error
        return member_;
    }
    int badGetter()
    {
        return member_;
    }
private:
    mutable int state_;
    int member_;
};

The test

int main()
{
    const A a1;
    a1.badGetter(); // doesn't work
    a1.goodGetter(); // works
    a1.hashGetter(); // works

    A a2;
    a2.badGetter(); // works
    a2.goodGetter(); // works
    a2.hashGetter(); // works
}

Read this for more information


Blair's answer is on the mark.

However note that there is a mutable qualifier which may be added to a class's data members. Any member so marked can be modified in a const method without violating the const contract.

You might want to use this (for example) if you want an object to remember how many times a particular method is called, whilst not affecting the "logical" constness of that method.


Meaning of a Const Member Function in C++ Common Knowledge: Essential Intermediate Programming gives a clear explanation:

The type of the this pointer in a non-const member function of a class X is X * const. That is, it’s a constant pointer to a non-constant X (see Const Pointers and Pointers to Const [7, 21]). Because the object to which this refers is not const, it can be modified. The type of this in a const member function of a class X is const X * const. That is, it’s a constant pointer to a constant X. Because the object to which this refers is const, it cannot be modified. That’s the difference between const and non-const member functions.

So in your code:

class foobar
{
  public:
     operator int () const;
     const char* foo() const;
};

You can think it as this:

class foobar
{
  public:
     operator int (const foobar * const this) const;
     const char* foo(const foobar * const this) const;
};

when you use const in the method signature (like your said: const char* foo() const;) you are telling the compiler that memory pointed to by this can't be changed by this method (which is foo here).


I would like to add the following point.

You can also make it a const & and const &&

So,

struct s{
    void val1() const {
     // *this is const here. Hence this function cannot modify any member of *this
    }
    void val2() const & {
    // *this is const& here
    }
    void val3() const && {
    // The object calling this function should be const rvalue only.
    }
    void val4() && {
    // The object calling this function should be rvalue reference only.
    }

};

int main(){
  s a;
  a.val1(); //okay
  a.val2(); //okay
  // a.val3() not okay, a is not rvalue will be okay if called like
  std::move(a).val3(); // okay, move makes it a rvalue
}

Feel free to improve the answer. I am no expert


The const keyword used with the function declaration specifies that it is a const member function and it will not be able to change the data members of the object.

참고URL : https://stackoverflow.com/questions/751681/meaning-of-const-last-in-a-function-declaration-of-a-class

반응형