Brise

[C++ 기본3] 4. 상수멤버함수 본문

프로그램/C,C++

[C++ 기본3] 4. 상수멤버함수

naudhizb 2022. 5. 15. 14:50
반응형

상수멤버함수는 실행시 모든 멤버 값들을 상수로 취급하는 함수이다.

잘 생각해보면 c언어에서 const struct 가 있듯이 c++언어에서는 const class가 있으며, 거기에다가 객체 지향 언어이므로 const class에서 사용할 수 있는 함수가 있어야 한다.

// 4_상수멤버함수1.cpp    119 page ~
#include <iostream>
class Point
{
public:
    int x, y;
    Point(int a = 0, int b = 0) : x(a), y(b) {}

    void set(int a, int b) { x = a; y = b; }

    void print() const   // 상수 멤버 함수
    {    
        // 상수 멤버 함수 안에서는 모든 멤버를 상수 취급 합니다
        // x = 100; // error

        std::cout << x << ", " << y << std::endl;
    }
};
int main() 
{
    // 왜 상수 멤버 함수가 "꼭" 필요한가 ?

    const Point p(1, 2);
    p.x = 10;        // error. p는 상수이므로
    p.set(10, 20);    // error.
    p.print();        // error. 호출되게 하려면 
                    // print() 가 상수 멤버 함수가 되야 합니다.

    // 핵심 : "상수 객체" 는 "상수 멤버 함수"만 호출할수 있습니다.
    // 121 page 아래 부분
}

객체가 상수객체인 경우 일반 멤버함수는 호출하지 못하고 상수객체함수만을 호출 할 수 있다.
아마 이 경우가 순수함수의 정의에 따르지 않을까??

일반적으로 실행시간을 최적화하고, 객체 관리를 위하여 함수 호출 시 최대한 call by value를 자제하고 call by reference를 사용한다.

이 경우 human error를 방지하기 위하여 getter 함수에 대하여 const reference를 활용하여 레페런스의 의도치 않은 변경을 막게 되는데 이 경우 일반 함수로 getter를 만들게 되면 함수호출을 하기 위해서는 꼭 상수멤버함수로 함수를 만들어 주어야 한다.

// 핵심 : 상수 멤버 함수는 선택이 아닌 "필수문법" 입니다.
//       객체의 상태를 수정하지 않은 모든 멤버 함수(getter)는
//       반드시 상수 함수로 해야 합니다.

class Rect
{
    int x, y, w, h;
public:
    Rect(int a, int b, int c, int d)
        : x(a), y(b), w(c), h(d) {}

    int getArea() const { return w * h; }
};
//void foo(Rect r) // call by value
void foo(const Rect& r) 
{
    int n = r.getArea(); //???
}

int main()
{
    Rect r(1, 1, 10, 10);
    int n = r.getArea(); // ok
    foo(r);
}

c++은 다형성을 제공하기 때문에 같은 함수 이름이라도 다른 인자를 갖는 다른 함수를 선언 가능하다. 상수 멤버함수에 있어서도 똑같이 적용이 된다.

#include <iostream>

class Test
{
public:
    // 상수 멤버 함수와 비상수 멤버함수을 동시제공 가능
    void foo()       { std::cout << __FUNCSIG__ << std::endl; }
    void foo() const { std::cout << __FUNCSIG__ << std::endl; }
};

int main()
{
    Test t; 
    t.foo();  // 1번 호출, 없으면 2번 사용

    const Test ct;
    ct.foo(); // 2번호출, 없으면 error
}

static 멤버 함수의 경우 객체 없이 호출이 가능하기 때문에 const를 붙일 수 없다.

#include <iostream>

// 참고 : static 멤버 함수에는 const를 붙일수 없습니다.
//       객체없이 호출가능하므로.

class Test
{
public:
    // 핵심 : 상수 멤버 함수는 선언부와 구현부 모두에 const를
    //            붙여야 합니다.  125 page
    void foo();
    void foo() const;
};
// 구글에서 "


void Test::foo()
{
    std::cout << __FUNCSIG__ << std::endl; 
}
void Test::foo() const 
{ 
    std::cout << __FUNCSIG__ << std::endl; 
}


int main()
{
    
}
반응형

'프로그램 > C,C++' 카테고리의 다른 글

[C++ 기본3] 7. 가상함수  (0) 2022.05.15
[C++ 기본3] 6. Upcasting  (0) 2022.05.15
[C++ 기본3] 5. 상속  (0) 2022.05.15
C++ Design Pattern  (0) 2022.04.07
[C++ 기본 3] 3. this  (0) 2022.04.04
[C++ 기본 3] 2. 정적 멤버  (0) 2022.04.04
[C++ 기본 3] 1. 객체복사  (0) 2022.04.04
Comments