structure(구조체)와 class는 무엇이 다를까? 먼저 정의하는 구조는 비슷하다.

structure는 member field, constructor(생성자), destructor(소멸자) 이 세 가지로 구성된다.

class는 위의 구조체 성분에 member fuction과 OOP(Object-Oriented Programming) 개념이 추가적으로 들어있다.

즉, class는 structure의 구성을 포함하는 개념이다.

(각 구성성분에 대한 설명은 ...참고)

 

structure의 member field가 외부에 쉽게 노출되어 사용하기 편하고 속도도 빠르나, 데이터 보호에는 취약하다.

structure는 중요 데이터를 묶는 data grouping 역할을 한다.

클래스는 data grouping 외에도 중요 데이터를 보호(information hiding)하고, OOP을 할 수 있게 한다.

 

 

 

예를 들어서 설명해보자. 학생에 대한 정보를 담는 구조체를 정의해보자.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
struct Student {
    char name[50];
    int age;
 
    Student(char* _name, int _age) //constructor -초기화
    {
        strcpy_s(name, _name);
        age = _age;
    }
    ~Student()                    //destructor
    {
        cout << "Die!" << endl;
    }
};
cs

 

 

 

 *CODE DESCRIPTION:

1. 이름이 Student인 structure 생성

2. char형 배열 크기 50을 갖는 이름이 name인 변수 선언 (50byte)

3. 나이 data를 저장하는 이름이 age인 변수 선언(4byte)              member field - data grouping에 해당하는 부분       

5. constructor는 structure의 member field를 초기화 해주는 기능을 한다.

7. strcpy_s는 c-style 문자열(char [] 타입)에 복사해주는 함수이다.

이 함수의 내부는 우리가 배열을 copy할 때 for문을 직접 작성하는 수고로움을 덜어준다.

6. destructor

14. structure 생성 시 {} 뒤에 반드시 ;(semi-colon)을 붙여줘야 한다.

 

 

위에서 우리는 class는 structure를 포함하는 개념이라고 했다.

그러면 class로 이것을 표현하고 부가적으로 어떤 기능들을 추가할 수 있는지 코드를 통해 살펴보자.

 

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
class Student {
private:
    char name[50];
    int age;
public:
    Student(char* _name, int _age); //constructor -초기화
    ~Student();                    //destructor
 
    void change(char* _name, int _age);    //특정 structure object의 member field 변경하는 함수
    void change(Student &s);    //객체 주소를 받아(주소에 의한 전달) 값 변경
    void change(Student s);    //객체 copy본을 받아(값에 의한 전달) 값 변경
};
Student::Student(char* _name, int _age) //constructor -초기화
{
    strcpy_s(name, _name);
    age = _age;
}
Student::~Student()                        //destructor
{
    cout << "Die!" << endl;
}
void Student::change(char* _name, int _age)    //특정 structure object의 member field 변경하는 함수
{
    strcpy_s(name, _name);
    age = _age;
}
void Student::change(Student &s)    //객체 주소를 받아(주소에 의한 전달) 값 변경
{
    strcpy_s(s.name,name);
    age = s.age;
}
void Student::change(Student s)        //객체 copy본을 받아(값에 의한 전달) 값 변경
{
    strcpy_s(s.name,name);
    age = s.age;
}
cs

 

 

 

 

 

어떤 것이 달라졌는가?

첫번째, member field를 private으로 선언하여 class 내부에서만 보이도록한다.

이것을 information hiding(정보보호) 또는 encapsulation(은닉화)라고 한다.

은닉화된 class는 외부에서 안의 데이터를 알 수 없다.

 

두번째, member function을 정의할 수 있다.

(여기서는 declaration과 definition을 나누었는데, 클래스는 이렇게 따로 분리할 땐 CLASS_NAME:: 을 추가해야됨을 잊지 말자.)

그래서 우리는 class와 관련된 기능을 수행할 수 있다. 예를 들어 Banking이라는 class에는 withdrawal이라는 기능(member function)을 구현할 수 있게 된다. 이렇게 되면 그냥 main에서 함수를 정의해서 사용하는 것보다 구조와 기능들이 명료해짐을 느낄 수 있다.

 

 *CODE DESCRIPTION:

27. 우리는 객체를 받아와서 class와 관련된 기능을 수행할 수 있다. 외부로 부터 객체(&를 이용)를 argument로 입력해주면

외부로부터 넘겨받은 객체의 data를 변경하는 함수이다. 이것은 단지 "주소에 의한 전달"개념을 짚고 넘어가기 위한 함수이므로

내부 기능은 큰 의미가 없다.

 

32. overloaded function(parameter의 type 또는 parameter의 수로 구분)이다. line27과 기능은 같다. 단지 주소로 받지 않고

객체의 copy본을 받았기 때문에 값을 변경한다해도 s자체는 함수를 시작하면서 생성된 object이고 이것은 이 함수가 끝나면서 소멸된다. 이 함수는 단지 "값에 의한 전달"개념을 짚고 넘어가기 위한 것이므로 프로젝트의 목적과 기능에 따라 line27 함수와 구분하여 사용하면 된다.

 

그렇다면 structure는 그 structure와 관련된 함수를 전혀 수행을 못 하는 것인가?

다음 코드를 살펴보자.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
struct Student {
    char name[50];
    int age;
 
    Student(char* _name, int _age) //constructor -초기화
    {
        strcpy_s(name, _name);
        age = _age;
    }
    ~Student()                    //destructor
    {
        cout << "Die!" << endl;
    }
};
Student change(char* _name, int _age)    //특정 structure object의 member field 변경하는 함수
{
    Student s(_name, _age);
    return s;
}
void change(Student &s, char* _name, int _age)    //객체 주소를 받아(주소에 의한 전달) 값 변경
{
    strcpy_s(s.name, _name);
    s.age = _age;
}
void change(Student s,char* _name, int _age)        //객체 copy본을 받아(값에 의한 전달) 값 변경
{
    strcpy_s(s.name, _name);
    s.age = _age;
}
 
cs

 

 

 

멤버함수들이 아닌 일반함수로 그 기능을 대체할 수 있다. 그러므로 CLASS_NAME::도 빠지게 되었다.

 

일반함수로 바뀌었기 때문에 class와 달리 객체와 연관된 member field와 member function의 연산을 바로 수행 할 수 없다.

(ex. Student S1을 선언하고 S1.change를 이용해 S1의 data와의 직접 연산을 할 수 없는 점)

 

따라서 line20, 25처럼 object를 받고 따로 데이터도 받아서 값을 바꿔주거나 line20 처럼 함수 내에서 object를 생성한 후

ojbect를 return하여 다른 object에 assign(할당)하는 방법 등을 생각해 볼 수 있다.

(Note. structure type도 fundamental type처럼 structure object에 assign이 가능하다는 점)

 

 

 

/*****************************************************************************************

Full Source Code: https://github.com/devgraphy/Cpp-200/tree/master/145

 

 

조언과 틀린 부분에 대해선 언제든지 지적부탁드리며, 보충설명이 필요한 부분에 대해 댓글을

남기시면 업데이트하거나 댓글 달아드리겠습니다.

 

매 포스팅과 source code는 추가적으로 업데이트 될 수 있습니다.

*****************************************************************************************/