C언어 구조체 사용하여 프로그래밍
C언어를 접해본 사람이라면, 구조체에 대해 알 것이다. C++에서의 클래스 개념은 구조체 개념이 확장된 것이라고 생각하면 쉽다. 어떻게 확장된 것인지 알아보기 위해 예를 들어서 알아보겠다. 먼저 C언어로 간단한 개인 정보를 입력받고 출력하는 프로그램을 만들어 보겠다.
#include <stdio.h>
typedef struct People
{
char name[10];
short age;
double height;
}PI;
void AddPeople(PI *p)
{
printf("Input information\n");
printf("name : ");
scanf("%s", p->name);
printf("age : ");
scanf("%hd", &p->age);
printf("height : ");
scanf("%lf", &p->height);
}
void ShowPeople(PI *p)
{
printf("%s | age : %hd, height : %lf\n", p->name, p->age, p->height);
}
int main()
{
PI data;
AddPeople(&data);
ShowPeople(&data);
return 0;
}
이름과 나이, 키를 입력받아 그것을 출력하는 프로그램이다. 여기서 사용된 변수와 함수들을 모아서 하나의 객체로 만들 것이다.
구조체를 클래스로 변경
프로그램에서 사용되는 작업들을 객체로 만들기 위해서는 작업에 사용되는 데이터도 객체에 포함시켜야 한다. 그래서 위의 소스에 있는 구조체 항목을 클래스 문법으로 변경해서 객체로 만들어줘야 한다.
멤버 변수(Member Variable)
class People
{
char name[10];
short age;
double height;
};
구조체에 선언되었던 세 변수들이 클래스 안으로 들어갔다. 이 때 이 변수들을 멤버 변수라고 한다.
접근 제한자
위와 같이 클래스를 선언한 후에 클래스에 속한 변수를 사용하기 위해서 아래와 같이 코드를 사용하면 오류가 난다.
People data;
data.age = 23;
위의 코드가 오류가 나는 이유는 클래스 문법 사용 시에 접근제한자라는 개념이 생겨나기 때문이다. 별도로 접근제한자를 쓰지 않으면 기본으로 'private'라는 접근제한자가 사용된다. 즉, 처음 선언한 클래스는 실제로는 아래와 같다는 말이다.
class People
{
private:
char name[10];
short age;
double height;
};
접근 제한자 |
기능 |
private |
객체 외부에서 멤버 변수를 직접적으로 접근할 수 없다. |
protected |
객체 외부에서 멤버 변수를 직접적으로 접근할 수 없다. |
public |
객체 외부에서 멤버 변수에 직접적으로 접근할 수 있다. |
오류가 난 이유는 기본적으로 접근제한자가 'private'로 지정되어 있어서 외부에서 멤버 변수로 접근할 수 없기 때문이다. 오류가 안나게 하려면 접근 제한자를 'public'으로 바꿔주면 된다. 하지만, 기본을 'private'로 지정하면서 외부에서의 접근을 막은 이유가 무엇일까? 바로 객체의 개념을 지키기 위해서이다. 되도록이면 객체는 'private'으로 사용하는 것이 객체를 제대로 사용하는 것이라 생각한다.
멤버 함수(Member Function)
클래스에 작업을 위한 변수들이 선언되었다. 하지만, 데이터만 있다고 객체가 쓸모있는 것이 아니다. 완성되기 위해서는 데이터를 사용하는 작업들이 있어야 하는데, 이것이 바로 함수이다. 이렇게 클래스 내부에 선언된 함수를 멤버 함수라고 한다. 같은 클래스 내에 멤버 변수와 멤버 함수가 선언되었으면 멤버 함수는 멤버 변수에 직접적으로 접근할 수 있다. 아래의 예를 통해 확인해보겠다.
class People
{
private:
char name[10];
short age;
double height;
void MyFunc()
{
age = 23;
}
};
멤버 함수에서 주의해야할 점이 있다. 멤버 함수 또한 함수이기 때문에 당연히 지역 변수를 선언할 수 있다. 이때 멤버 함수에서 선언한 지역 변수와 멤버 변수의 이름이 같은 경우에는 오류가 나므로 주의해야 한다. 일반적으로 멤버 변수의 경우에는 'm_'을 붙여 멤버 변수임을 상기시킨다.
멤버 함수를 사용하는 이유는 멤버 변수와 접근 제한자의 특징을 생각하면 쉽게 생각할 수 있다. 'private' 접근 제한자가 걸린 멤버 변수는 외부에서 접근이 불가능하다고 했다. 하지만, 같은 클래스 내의 멤버 함수는 제한없이 직접적으로 접근할 수 있다고 했다. 이것이 바로 멤버 함수의 사용 이유이다. 간단하게 멤버 변수와의 연결고리 역할을 해준다고 생각하면 된다. 어떤식으로 사용하는지 예를 들어 확인해보겠다.
class People
{
private:
char m_name[10];
short m_age;
double m_height;
public:
void SetAge(int a_age)
{
m_age = a_age;
}
};
int main()
{
People data;
data.SetAge(23);
return 0;
}
위의 소스를 보면 멤버 함수를 선언하는 부분에도 접근 제한자가 있는 것을 확인할 수 있다. 이 때 접근 제한자로 'public'을 준 이유는 멤버 함수는 외부에서 사용할 수 있어야 멤버 변수의 정보를 사용할 수 있기 때문이다. 이렇게 외부에서 멤버 변수를 간접적으로 사용할 수 있도록 도와주는 멤버 함수를 인터페이스 함수(Interface Function)라고도 한다.
클래스화 완성시키기
이제 클래스화를 어떻게 하는지 알았으므로 완성시켜 보겠다. 처음 C언어로 만든 프로그램의 기능인 'AddPeople()'과 'ShowPeople()' 함수를 클래스의 인터페이스 함수로 추가시킨다. 아래가 완성된 코드이다.
#include <stdio.h>
class People
{
private:
char m_name[10];
short m_age;
double m_height;
public:
void AddPeople()
{
printf("Input information\n");
printf("name : ");
scanf("%s", m_name);
printf("age : ");
scanf("%hd", &m_age);
printf("heigth : ");
scanf("%lf", &m_height);
}
void ShowPeople()
{
printf("%s | age : %hd, height : %lf\n", m_name, m_age, m_height);
}
};
int main()
{
People data;
data.AddPeople();
data.ShowPeople();
return 0;
}
처음 C언어로 이루어진 코드와 비교해보면 확실히 단순해진 것을 확인할 수가 있다. C언어에 있던 구조체 포인터가 모두 사라져서 코드가 많이 쉬워졌다.
클래스의 장점
클래스를 사용하는 이유는 크게 두 가지가 있다. 첫 번째는 자주 사용하는 기능들을 하나의 객체로 만들어 코드의 중복을 줄이고 그 코드를 재사용하기 위해서이다. 두 번째는 프로그램의 기능을 변경해야 하는 경우에 발생하는 작업을 최소화하기 위해서이다. 프로그래밍 중 발생하는 변경 요소는 대부분 데이터와 관련되어 있다. 클래스를 사용하게 되면 이 데이터와 관련된 모든 부분들이 멤버 함수로 만들어지기 때문에 변화에 대처하기 좋은 소스가 되는 것이다.
'C++ > C++ 기초' 카테고리의 다른 글
네임스페이스 (Namespace) (0) | 2019.09.09 |
---|---|
객체 파괴자 (0) | 2019.09.05 |
객체 생성자 (0) | 2019.09.02 |
오버로딩(Overloading) (0) | 2019.09.01 |
C++ 개요 (0) | 2019.08.31 |