Home  |   방명록 2021-10-18 (월) 
Untitled Document
  S e a r c h
M e n u
프로그램
개발자료
고전음악실
대청마루
집주인
비망록
갤러리
  B o a r d
게시판
Untitled Document
개발자료 Software / Hardware 개발 관련 정보

C 개발자를 위한 C++

C 개발자를 위한 C++

 

1. C++ 은 C 언어 기반이다.

C++은 C를 포함하는 전혀 새로운 프로그래밍 언어이다.
객체 지향을 하려면 C로는 할 수 없고 C++로 해야만 한다.
이 말들은 모두 잘못된 이해입니다.

C++은 C를 기반으로 하는 언어입니다.
C와 다른 전혀 별개의 새로운 언어가 아닙니다.
C++은 1983년 AT&T 벨 연구소에서 만들었다는데 원래 이름은 C with Classes 였습니다.
C와 전혀 다른게 아니라 C와 같은데 거기에 코딩의 자동화 기능을 추가한 것이다고 할 수 있습니다.
물론 개념적으로는 C++은 C를 포함하는 더 큰 집합이고
둘 간의 교집합이 온전한 C언어가 됩니다.

C언어 < C++ 언어

하지만 C++은 C언어에다가 추상적인 개념이 더해진 것일뿐 별개의 실체는 없습니다.
그 실체는 내부적으로는 모두 C를 통해 구현됩니다.
C 소스를 컴파일 하면

C 소스 --> 어셈블리 소스 --> 기계어

와 같이 변환 됩니다.
그렇다면 C++ 소스를 컴파일 하면

C++ 소스(추상적) --> C 소스(실체화) --> 어셈블리 소스 --> 기계어

이렇게 변환된다고 할 수 있습니다.

 

2. 클래스(Class)

C++의 대표적인 개념으로 class 가 있습니다.
처음 배울 때는 생소하고 어렵게 느껴지는 개념입니다.
하지만 C++은 C 기반이라고 했습니다.

class MyClass {
    char a;
    void function1();
};

기본적인 class 는 위와 같이 선언됩니다.
이를 C언어로 바꾸면 다음과 같습니다.

typedef struct {
    char a;
    void (*function1)();
} MyClass;

즉, classtypedef struct 와 같다 쯤으로 이해하시면 됩니다.
사용할 때는 둘 다 같습니다. C에서는 먼저 함수 포인터의 값을 지정해 줘야 겠지만요.
다음과 같이 해주면 변수가 생성됩니다.

MyClass   obj;

하지만 class에는 몇 가지 개념들이 추가되어 있습니다.
대표적으로 생성자, 소멸자, 캡슐화(Encapsulation), 상속(Inheritance) 등이 있습니다.

 

3. 생성자와 소멸자

생성자와 소멸자는 각각 class 변수가 생성될 때나 수명을 다하고 메모리에서 제거 될 때
자동으로 호출되는 함수입니다.
보통 생성자에는 class에서 사용하는 변수의 초기화 코드를 타이핑해 넣습니다.
그리고 소멸자에는 동적으로 할당한 메모리를 반환하는 코드를 타이핑해 넣습니다.

class MyClass {
    char a;
    void function1();

public:
    void MyClass();
    void ~MyClass();
};

위 에서 class 의 이름과 동일한 이름의 MyClass() 함수가 생성자이고
class 이름 앞에 ~가 붙은 ~MyClass() 함수가 소멸자 입니다.

C++에서는 class 변수를 사용할 때

MyClass   obj;

이렇게 변수 선언만 해 주면 제일 먼저 자동으로 생성자인 MyClass() 함수를 호출합니다.
그리고 메모리에서 제거 될 때는 자동으로 소멸자인 ~MyClass() 함수를 호출해 줍니다.

그런데 자동이라는게 뭘까요?
C++ 내부적으로는 자동이란게 없습니다.
컴파일 하려면 실체가 있어야 컴파일을 할 수 있기 때문입니다.
사실 코드가 눈에 보이지 않을 뿐이지 필요한 곳곳에 보이지 않는 코드를 자동으로 삽입해 주는 겁니다.
이를 C로 표현하면 다음과 같습니다.

typedef struct {
    char a;
    void (*function1)();
    void (*createMyClass)(void *pObj);
    void (*deleteMyClass)(void *pObj);
} MyClass;

MyClass   obj;

obj.createMyClass(&obj); //-- 생성자와 같은 역할
.......
//마지막으로 obj 사용이 완료된 후
obj.deleteMyClass(&obj); //-- 소멸자와 같은 역할

class 라는 폼나는 개념을 만들었는데 class 데이터 초기화나
소멸 기능을 일일히 타이핑 하면 너무 없어 보입니다.
그러니 생성자와 소멸자라는 개념을 만들어 일일히 타이핑 할 필요 없이
자동으로 호출하도록 만들었습니다.
하지만 어디까지나 호출하는 부분이 눈에 보이지만 않을뿐 컴파일 시에는
위처럼 만들어 질 겁니다.

 

4. 캡슐화(Encapsulation)

캡슐화는 class 외부에 데이터나 함수를 감추는(은닉하는) 기능입니다.
class 내부에서만 사용하는 변수나 함수를 외부에 노출할 필요가 없습니다.
여러 명이 팀으로 개발할 때 내가 한 class 를 담당했다면
외부에서 건드릴 필요가 없는 것은 감춰두는 것이 함수나 변수를 잘 못 사용해서
버그를 만드는 일을 방지 할 수 있습니다.

class MyClass {
public:
    char a;
    void function1();

public:
    void MyClass();
    void ~MyClass();

protected:
    void family_only();

private:
    void no_touch();
};

public 은 C에서 처럼 아무런 접근 제한이 없는 것 입니다.
변수 a 와 function1() 함수는 외부에서 무제한으로 접근할 수 있습니다.

protected 는 자기 클래스나 상속받은 자식 클래스에서 만 접근을 허용합니다.
family_only() 함수는 본인과 가족 관계자 외에는 사용할 수 없습니다.

private 은 자기만 사용할 수 있습니다.
no_touch() 함수는 class 본인만 접근 할 수 있습니다.

하지만 접근 권한이란 어디까지나 코딩 할 때의 이야기 입니다.
컴파일러와 프로그래머 간의 약속일 뿐입니다.
강제적으로 메모리 포인터에 의해서는 아무곳이나 접근할 수 있으니까요.
실제 실행시 잘못된 메모리 접근까지 막아주는 것은 아닙니다.

 

5. 상속(Inheritance)

상속이란 비슷한 속성의 class 를 만들 필요가 있을때
기본 class 의 것을 가져다 쓸 수 있게 만든 개념 입니다.

class ChildClass : public MyClass {
public:
    char b;
    void function2();
};

위와 같이 선언하면 ChildClass 는 부모인 MyClass 의 멤버를
protected 와 public 으로 선언된 멤버를 따로 선언할 필요 없이 사용할 수 있습니다.

ChildClass cobj;

cobj.function1();

이 가능하다는 말입니다. function1() 을 따로 선언하지 않아도 부모의 function1() 을
그대로 상속 받아 호출이 가능합니다.

이것을 C 개념으로 보면,

typedef struct {
    char a;
    void (*function1)();
} MyClass;

typedef struct {
    MyClass parent;
    char b;
    void (*function2)();
} ChildClass;

ChildClass cobj;

cobj.parent.function1();

위와 같습니다.
이런 상속 개념이 필요한 이유는 비슷한 속성군의 함수를 하나만 만들어서
공유 할 수 있다는 장점과
이를 관리하는 입장에서도 하나의 포인터로 각 class 변수를 가리킬 수 있습니다.

C++에서는,

MyClass obj;
ChildClass cobj;
MyClass   *pObj;

pObj = &obj;
pObj = (MyClass*)&cobj;

마찬가지로 C에서도,

MyClass obj;
ChildClass cobj;
MyClass   *pObj;

pObj = &obj;
pObj = (MyClass*)&cobj;

이렇게 하나의 포인터로 관리하면 구조적인 프로그래밍이 가능합니다.
예를들어 그림판 프로그램이라면 직선, 사각형 등을 그리는 툴이 각각 존재합니다.
pObj 포인터를 현재 선택된 툴의 포인터라고 하면
각각의 그리기 함수를 이 공통 포인터를 통해 접근할 수 있습니다.

 

6. 다형성(Polymophism)

다형성이란 쉽게 말하면 동일한 이름의 함수를 여러개 쓸 수 있다는 말입니다.
단, 구분이 필요하므로 함수의 리턴값이나 변수 중 어느것은 달라야 합니다.

class MyClass {
public:
    char a;
    void function1();
    char function1();
    void function1(char in);
    void function1(int in);
};

위와 같이 같은 이름의 함수를 여러개 선언 할 수 있습니다.
변수에 따라 같은 기능을 하는 함수가 여러개 필요할 때 함수 이름을
각각 달리 하는 것 보다는 같은 이름을 사용하는게 직관적일 겁니다.
C에는 이런 기능이 없습니다.
함수 이름이 같으면 에러가 납니다.
그럼 C++은 어떻게 이 문제를 해결할까요.
사실 C++에서는 function1() 라고 선언 했을때 보이는 것과 달리
내부적으로는 ??0Cfunction1@@QAE@XZ() 같은 식으로 이름을 바꿔 관리합니다.
이름이 똑같으면 C++ 자신도 구분할 방법이 없습니다.
밖으로 보이는 것만 똑똑한 것 처럼 보일 뿐
안에서는 C와 똑같이 함수명을 각각 구분하기 위해 유니크한 함수명을 프로그래머 몰래 만듭니다.

강제적으로 함수 이름을 바꾸지 않도록 할 수 있습니다.
그래야 C 모듈과 인터페이스를 할 수 있으니까요.

#ifdef __cplusplus
extern "C" {
#endif

void intrinsic_func();

#ifdef __cplusplus
}
#endif

위 처럼 선언하면 내부적으로 함수의 이름을 바꾸지 않습니다.

 

7. 객체(Object)와 객체지향(Object Oriented)

객체란 작게는 char 변수 하나가 될 수도 있고,
혹은 여러 함수와 변수가 모인 구조체일 수도 있고,
크게는 프로그램도 하나의 객체가 될 수도 있습니다.

객체지향이란 객체 하나가 온전한 생명체 처럼 자기가 필요한 모든 기능을
포함하는 것입니다.
아메바 같은 단세포이거나 여러 세포가 결합된 다세포이거나
인간처럼 복잡한 생명체가 각각 객체입니다.
어떤 특징을 유지한채 구분할 수 있는 최소 단위로 모듈화, 블럭화를 해서 최대한 분리하는 것입니다.
이렇게 해서 기능을 분리하고 코드의 재활용성을 높이고 버그를 줄일 수 있습니다.
이상적으로는 팀 단위 개발에서 각자 모듈을 개발해서 결합하여 최종 제품을 만든는 것입니다.
레고 블럭 처럼 모듈로 만들어 놓으면 자동차나 비행기를 만들 때
블럭을 하나씩 가져다 끼워넣을 수 있습니다. 바퀴, 의자 등등.. 

하지만 객체지향이란 개념이 결코 쉬운 개념이 아닙니다.
제대로 객체지향을 구현하려면 한 10년 정도는 경력이 쌓여서
프로젝트 전체를 설계할 수 있는 아키텍트의 수준까지 올라야 합니다.

그럼 C++ 로만 객체지향을 할 수 있을까요?
C 시절에는 객체지향을 하지 못했을까요?
단지 C++이 객체지향 기반(ready) 언어라는 차이점입니다.

 

8. 기타

증가 연산자: a++ 은 C로 표현하면 a = a + 1 입니다. 여기서 C++의 이름이 나왔습니다.
감소 연산자: a-- 는 C로 표현하면 a = a - 1 입니다.
new: malloc() 함수와 같은 역할을 합니다.
delete: free()  함수와 같은 역할을 합니다.
virtual (가상함수): class에 virtual로 선언된 함수는 자식 class에 동일 함수가 존재할 때
부모의 함수를 호출하지 않고 자식의 함수를 호출합니다.
컴파일 할 때 적절한 함수의 호출로 대치하는 것입니다.
template: C++의 강력함을 가져다 주는 특징입니다.
함수는 결정돼 있지만 데이터 타입은 결정되지 않은 특징이 있고 데이터 형은 탬플릿을 사용할 때 결정됩니다.
#define을 이용해 연산 기능을 정의하는 것의 확장판이라 볼 수 있습니다.

 

이렇게 C++의 대표적 일부 기능들과 C의 관계를 알아 봤습니다.
C++이 C와 크게 다르지 않다는 걸 아실 겁니다.
C++이 장난으로 만들었다는 인터넷에 떠도는 글도 있지만 C++이 C를 자동화한것 뿐이다는 말도 크게 틀리지 않구요.
이상 C++ 만든 사람이 보면 헛소리! 라고 할지도 모를 강좌였습니다.

2013-09-13 [조회: 5407]

이전글: 안드로이드 개발 환경 설정
다음글: [FOSD] 모든 한글 출력이 가능한 한글 OSD IC

목록보기
 
이름 암호
(스팸 방지용)오늘의 날짜를 숫자만으로 입력하세요.(예: 12)

비밀번호
목록보기
 
Copyright ⓒ 2021 All Rights Reserved.