C++ 클래스의 완성

‍정진철·2022년 9월 3일
0

C++

목록 보기
7/18

참조: 윤성우의 열혈 c++

1) 정보은닉

  • 점을 표현한 Point 클래스의 멤버변수 x,y는 public으로 선언되어서 어디서든 접근이 가능.
  • 직사각형을 표현할 두개의 Point객체 생성. 이렇듯 멤버변수가 public으로 선언되며, 구조체 변수를 초기화하듯이 초기화 가능.
  • 생성한 Point객체를 이용해 Rectangle 객체 생성 및 초기화.
#include <iostream>

using namespace std;

class Point
{
public:
    int x; // x는 0이상 100이하
    int y; // y는 0이상 100 이하
};

class Rectangle
{
public:
    Point upLeft;
    Point lowRight;

public:
    void ShowRecInfo()
    {
        cout << "좌 상단: " << '[' << upLeft.x << ",";
        cout << upLeft.y << ']' << endl;

        cout << "우 하단: " << '[' << lowRight.x << ",";
        cout << lowRight.y << ']' << endl;
    }
};

int main(void)
{
    Point pos1 = {-2, 4};
    Point pos2 = {5, 9};
    Rectangle rec = {pos2, pos1};
    rec.ShowRecInfo();

    return 0;
}

문제 발생

  • 점의 좌표는 0이상 100이하여야 하는데 그렇지 못한 Point 객체 생성됨.
  • 직사각형을 의미하는 Rectangle 객체의 좌표값이 옳지 못함.

따라서, 제한된 방법으로의 접근만 허용해서 잘못된 값이 저장되지 않도록 해야한다.

해결 방법

  • 먼저 멤버변수 x,y를 private으로 선언해 무작위로 값을 변경하는걸 사전에 방지 (정보 은닉).
  • 대신에 값의 저장 및 참조를 위한 '함수 정의'
  • InitMembers, SetX, SetY는 0이상 100이하의 범위의 값이 전달되지 않을시 오류 뱉음.

따라서, 멤버변수를 private으로 선언하고 해당변수에 접근하는 함수를 별도로 정의해서 안전한 형태로 멤버변수의 접근을 유도하는것이 바로 '정보은닉'이다.

<Point.h>

#include <iostream>

using namespace std;

class Point
{
private:
    int x;
    int y;

public:
    bool InitMembers(int xpos, int ypos);
    int GetX() const;
    int GetY() const;
    bool SetX(int xpos);
    bool SetY(int ypos);
};

<Point.cpp>

#include <iostream>
#include "Point.h"
using namespace std;


bool Point:: InitMembers(int xpos , int ypos)
{
    if(xpos < 0 || ypos < 0)
    {
        cout << "값의 범위가 유효치 않음" << endl;
        return false;
    }
    x = xpos;
    y = ypos;
}

// Get 함수는 '반환' Set 함수는 '저장'
int Point :: GetX() const //const 함수 
{
    return x;
}

int Point :: GetY() const
{
    return y;
}

bool Point:: SetX(int xpos)
{
    if(xpos<0 || xpos > 100)
    {
        cout << "잘못된 값 전달" << endl;
        return false;
    }
    x= xpos;
    return true;
}

bool Point:: SetY(int ypos)
{
    if(ypos<0 || ypos>100)
    {
        cout << "잘못된 값 전달" << endl;
        return false;
    }
    y=ypos;
    return true;
}
  • 참고로, Get,Set과 같은 함수들을 '엑세스 함수'라 하는데 이들은 멤버변수를 private 으로 선언하면서 클래스 외부에서 멤버변수 접근을 목적으로 정의 되는 함수들이다.
  • 이러한 함수들은 정의는 되있으나 호출되지 않은 경우가 많다.

Rectangle Class

<Rectangle.h>


#include "Point.h"

class Rectangle
{
private:
    Point upLeft;
    Point lowRight;

public:
    bool InitMembers(const Point &ul, const Point &r);
    void ShowRecInfo() const;
};

<Rectangle.cpp>

#include <iostream>
#include "rectangle.h"

using namespace std;

bool Rectangle::InitMembers(const Point &ul, const Point &lr)
{
    if (ul.GetX() > lr.GetX() || ul.GetY() > lr.GetY())
    {
        cout << "잘못된 위치정보 전달" << endl;
        return false;
    }
    upLeft = ul;
    lowRight = lr;
    return true;
}

void Rectangle::ShowRecInfo() const
{
    cout << "좌 상단: " << '[' << upLeft.GetX() << ",";
    cout << upLeft.GetY() << ']' << endl;
    cout << "우 하단: " << '[' << lowRight.GetX() << ",";
    cout << lowRight.GetY() << ']' << endl;
}

const 함수

  • const는 해당 함수 내에서는 멤버변수에 저장된 값을 변경하지 않겠다는 의미이다.
  • 따라서 const 선언이 추가된 멤버함수 내에서 멤버변수의 값을 변경하는 코드가 삽입된다면 컴파일 에러 발생됨
  • 추가적으로 const가 붙여진 함수 내에서 const가 붙여있지 않은 함수를 불러낼 때에는 오류가 발생한다
  • 해당 함수내에서 멤버변수를 변경하지 않더라도 말이다.
  • 따라서 부르는 함수에서 const함수를 붙여줬다면 불러낼 함수에서도 역시const를 붙여줘야한다. (안전성 확보)
profile
WILL is ALL

0개의 댓글