프로그램/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()
{
}
반응형