MousePoint pt[3];
일반 변수의 배열과 동일하다.
다만 데이터 한 단위가 int는 4바이트인데 x,y로 이루어져있는 8바이트다.
pt[0].setXY(10,20);
pt[1].setXY(100,200);
MousePoint pt[3] = {MousePoint(10,20), MousePoint(30,40), MousePoint(50,60)};
#include<iostream>
using namespace std;
class MousePoint
{
private:
int x;
int y;
public:
MousePoint();
MousePoint(int nX, int nY);
void SetXY(int nX, int nY);
inline int GetX() { return x; }
inline int GetY() { return y; }
};
MousePoint::MousePoint()
{
x = 0;
y = 0;
}
##
MousePoint::MousePoint(int nX, int nY)
{
x = nX;
y = nY;
}
void MousePoint::SetXY(int nX, int nY)
{
x = nX;
y = nY;
}
void main()
{
MousePoint pt[3] = {
MousePoint(10,20),
MousePoint(30,40),
MousePoint(50,60)
};
for (int i = 0; i < 3; i++)
{
cout << "pt[" << i << "] = " << pt[i].GetX() << ", " << pt[i].GetY() << endl;
}
}
출력결과
pt[0] = 10, 20
pt[1] = 30, 40
pt[2] = 50, 60
한 줄짜리 코드는 클래스 내부에서 처리해도 된다. 인라인으로 처리할 수 있다.
MousePoint *pObj;
MousePoint pt(10,20);
pObj = &pt;
포인터는 주소값만을 저장하고, 주소값은 정수로 저장되므로 4바이트.
void main()
{
MousePoint* pObj;
MousePoint pt(10, 20);
pObj = &pt;
cout << pObj->GetX() << " " << pObj->GetY() << endl;
}
출력결과
10 20
-> : 간접 참조 연산자
. : 직접 참조 연산자
멤버 변수의 메모리 블록은 별도. 멤버 함수의 메모리 블록은 공유
멤버 함수 입장에서 어떤 객체가 자기를 호출했는지 알 수 있는가?
어떤 객체가 호출했는지 알 수 없으므로 이 때 필요한 정보가 바로 this 포인터이다.
void MousePoint::SetXY(int x, int y)
{
this -> x = x;
this -> y = y;
}
void main()
{
MousePoint pt(10, 20);
pt.SetXY(100, 200);
cout << pt.GetX() << " , " << pt.GetY() << endl;
}
출력결과
100, 200
전달인자와 멤버변수의 이름이 같을 때는 구분할 수가 없다.
이런 경우 멤버변수를 나타내는 x,y 앞에 this 포인터를 붙여줌으로써 현재 호출한 객체의 멤버변수임을 명시한다.
void SetRect(MousePoint pt1, MousePoint pt2)
{
cout << pt1.GetX() << ", " << pt1.GetY() << endl;
cout << pt2.GetX() << ", " << pt2.GetY() << endl;
pt1.SetXY(1000, 2000);
cout << pt1.GetX() << ", " << pt1.GetY() << endl;
}
void main()
{
MousePoint mp1(10,20), mp2(100,200);
SetRect(mp1, mp2);
cout << mp1.GetX() << ", " << mp1.GetY() << endl;
}
출력결과
10, 20
100, 200
1000, 2000
10, 20
메모리 공유가 아닌 값이 복사가 되는 방식이기 때문에 setRect 함수에서 변경된 멤버변수의 값이 main 함수에서는 변하지 않는다.
객체가 복사가 된다는 것은 객체의 멤버 변수가 그대로 복사가 된다는 의미이다.
결과를 보면 예상과 다름.
외부의 mp1 객체가 pt1 객체로 값을 넘겨준다.
setXY()함수를 통해 pt1 객체의 멤버 변수 값을 1000으로 변경한다.
mp1과 pt값을 복사하고 받는 별도의 메모리이지 결코 하나가 아니다.
void CopyObject(MousePoint pt1, MousePoint pt2)
{
pt1 = pt2; // pt2가 pt1에 복사
cout << pt1.GetX() << "," << mp1.GetY() << endl;
}
void main()
{
MousePoint mp1(10,20), mp2(100,200);
cout << pt1.GetX() << "," << mp1.GetY() << endl;
}
출력결과
100, 200
10, 20
CopyObject 함수에 각 객체를 넘겨줌으로써, 객체의 복사가 이루어짐.
출력 결과를 보면 우리가 예상한 100, 200이 아닌 10, 20이 출력.
이유는 실 매개변수와 형식매개변수의 메모리 관리가 별도로 이루어지고 있기 때문이다. 이것이 값 전달 방식의 한계이고 단점이다.
결국 주소값을 공유하는 포인터.
매개변수를 넘길때는 그냥 넘기지만, 받는 쪽에서는 주소값을 받는다.(=별칭) C++에서는 주소연산자가 아니라 별칭이라 부른다.
void CopyObject(MousePoint &pt1, MousePoint &pt2) // 별칭
{
pt1 = pt2;
cout << pt1.GetX() << ", " << pt1.GetY() << endl;
}
void main()
{
MousePoint mp1(10, 20), mp2(100, 200);
CopyObject(mp1, mp2);
cout << mp1.GetX() << ", " << mp1.GetY() << endl;
}
출력결과
100, 200
100, 200
MousePoint CopyObject(MousePoint &pt1, MousePoint &pt2)
{
pt1 = pt2;
return pt1;
}
함수 결과 반환 시 결과값을 저장하기 위한 별도의 메모리가 할당
MousePoint & CopyObject(MousePoint &pt1, MousePoint &pt2)
{
pt1 = pt2;
return pt1;
}
class MousePoint
{
private:
int x;
int y;
public:
MousePoint();
MousePoint(int nX, int nY);
void SetXY(int nX, int nY);
inline int GetX() const { return x; }
inline int GetY() const { return y; }
};
각 멤버 함수명 뒤에 const라는 예약어를 붙여주면 된다.
멤버함수 정의 시에도 const 예약어를 붙여주어야 한다.
멤버함수는 객체의 멤버변수를 변경할 수 없는 읽기 전용 함수
const 멤버 함수는 const로 지정되지 않은 다른 멤버함수도 호출할 수 없다.
읽기전용으로 지정된 const 멤버함수에서 const로 지정되지 않은 멤버함수를 호출함으로써 간접적으로 객체의 멤버변수를 변경시킬지도 모르는 가능성을 배제시키기 위함이다.
const로 선언된 멤버함수에서 객체의 데이터를 변경하려고 시도한다면 다음과 같은 에러메시지를 보게 된다.
l-value specifies const object
set()과 같은 멤버변수에 접근하는 함수는 const 멤버함수로 사용하면 안 되고, get()과 같이 데이터의 변화 없이 단순히 값을 반환하거나 화면에 출력하는 기능을 하는 함수를 const 멤버함수로 선언하는 것이 바람직하다.
const MousePoint pt1(10,20);
const MousePoint pt1(10,20);
MousePoint pt2(100, 200);
pt1 = pt2; // 에러가 발생한다.
다음과 같은 에러를 유발시킨다.
const 객체는 데이터 멤버를 변경할 수 있는 멤버함수 호출 허용 금지
pt1.SetXY(50,100) //에러가 발생하다.
다음과 같은 에러를 유발시킨다.
const 멤버 함수들은 호출이 가능하다.
pt1.GetX();
pt1.GetY();
멤버 변수를 변경하지 않고 저장되어있는 값을 반환하고 있음.