'C∫C++'에 해당되는 글 3건

  1. 2017.04.15 [STL] 템플릿을 이용해 Stack Calss 만들기.
  2. 2017.04.14 [C++] 함수 포인터
  3. 2017.01.15 객체지향.

[STL] 템플릿을 이용해 Stack Calss 만들기.



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
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
#include <iostream>
using namespace std;
 
#define    MAX        9
 
 
template <class T>
class Stack{
private:
    T Data;
    Stack* pUnder;
    Stack* pHead;    
public:
    Stack()   { pHead = NULL;}
    ~Stack()  { Clear(); delete pHead;}
 
    // 정보 저장.
    void push(T Data)
    {
        Stack* NewNode = new Stack;
        NewNode->Data = Data;
        NewNode->pUnder = NULL;
 
        if(pHead != NULL)
            NewNode->pUnder = pHead;
        pHead = NewNode;
    }
 
    // 정보 출력.
    T peek()
    {
        if(pHead == NULL)
            return -1;
 
        return pHead->Data;
    }
 
    // 정보 삭제.
    void pop()
    {
        if(pHead == NULL)
            return;
 
        Stack* pRemove = pHead;
        pHead = pHead->pUnder;
        delete pRemove;
    }
 
    // 모든 정보를 지운다.
    void Clear()
    {
        while(pHead != NULL)
        {
            Stack* pRemove = pHead;
            pHead = pHead->pUnder;
            delete pRemove;
        }
        pHead = NULL;
    }
};
 
void main()
{
    Stack<int> s;
 
    for(int i = 0; i < MAX; i++)
        s.push(i);
 
    for(int i = 0; i < MAX; i++)
    {
        printf("%d ", s.peek());
        s.pop();
    }
}
cs


자세한 설명은 생략한다.



결과



'C∫C++' 카테고리의 다른 글

[C++] 함수 포인터  (0) 2017.04.14
객체지향.  (0) 2017.01.15

[C++] 함수 포인터


포인터 변수는 다른변수의 주소를 보관한다.

변수가 메모리에 위치하고, 각 메모리 공간마다 주소를 가지고 있기에 가능한 일이다.


변수를 가리키는 포인터라면 변수에서 값을 읽거나, 값을 쓰는 용도로 사용할 수 있다.

하지만, 함수의 경우는 그런 작업이 불가능하다. 대신 함수의 포인터를 사용해서는 그 함수를 호출할 수 있다.


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
#include <iostream>
using namespace std;
 
void Cat();
void Dog();
void main()
{
    void (*p)();
    p = &Dog;
    
    (*p)();
 
    p = &Cat;
    (*p)();
}
 
void Cat()
{
    printf("야옹\n");
}
 
void Dog()
{
    printf("멍멍\n");
}
cs



결과




함수역시 메모리 어딘가에 보관된다.

하지만 일반적으로 변수들을 보관하는 메모리 공간과 함수들을 보관하는 메모리 공간이 어느 정도 떨어져 있게 된다.

어쨌든, 변수 p에는 Dog()의 시작주소가 들어가게 된다.




변수에 대한 포인터에 경우 그 포인터가 가리킬 수 있는 타입을 따로 지정해주었다.

함수 포인터도 마찬가지다. 포인터가 가리킬 수 있는 함수의 종류를 지정해 주어야 한다.

함수의 종류란 함수의 반환 값과 시그니처를 의미한다.


※시그니처란?

void Point(int a, int b);

이러한 함수가 있다고 하자.

함수의 시그니처란 함수의 원형에서 인자 부분을 의미한다. (int a, int b)

Point함수의 시그니처는 어떻게 되지? 라고 물어본다면, 정수 타입 2개만 받으면 된다.

라고 답변 해주면 된다.



반환 값, 인자가 있는 함수 포인터는 어떻게 쓸까?


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
#include <iostream>
using namespace std;
 
int Cat(int a, char *b);
void main()
{
    char b[] = "야옹";
    int (*p)(int,char*);
    p = &Cat;
 
    (*p)(5,b);
}
 
int Cat(int a, char *b)
{
    for(int i = 0; i < a; i++)
        printf("%s\n",b);
 
    return a;
}
cs



결과




※ 배열의 이름은 주소를 의미한다.

마찬가지로 함수의 이름은 주소를 의미한다.

그렇기 때문에 p = Dog;도 가능하다.

하지만 이 문장이 Dog의 주소를 얻고있는 것이라고 알아보기 힘들기 때문에 지양하도록 하자.


'C∫C++' 카테고리의 다른 글

[STL] 템플릿을 이용해 Stack Calss 만들기.  (0) 2017.04.15
객체지향.  (0) 2017.01.15

객체지향.


▷ 객체지향 프로그래밍( Object-Oriented Programming )


- OOP를 사용한 프로그램에는 전체 혹은 대부분의 작업이 '객체'를 통해서 이루어진 것이다.

알아두어야 할 것은 OOP는 일종의 '개념'에 가까울 뿐, 정확하고 구체적인 프로그래밍 기법이 아니다.



 OOP는 무엇인가?


- 프로그램의 구조를 여러 독립된 '객체(Object)'들의 구성으로 보는 관점이다.

=> 명령어의 목록으로 보는것이 아닌 여러 '객체'들의 상호작용을 바탕으로 프로그램을 구성하는 것을 말한다.


객체란? : - 저장공간에 할당된 공간을 의미. (== 메모리 상에서 특정 기능을 수행할 수 있는 것.)




▷ OOP는 객체가 다인가?


아니다, OOP에서 등장하는 대표적인 것으로 클래스(calss)라는 것이 있다.


※ 클래스란?

- 객체들의 변수와 메서드(함수)를 정의하는 일종의 템플릿.

=> 일종의 틀 이라고 생각하면 된다. 변수와 메서드를 규격화 한 것이라 볼 수 있다.


이 틀(class)로 만든 객체는 무엇이라 할까?

=> 어떤 클래스로부터 객체를 생성하는 것을 인스턴스화(instatiation)이라 하고, 

이를 통해 만들어진 객체를 인스턴스(instance)라 한다.


※ 클래스가 객체인지는 사용하는 언어에 따라 달라진다.




▷ 클래스만 잘 알면 OOP를 잘 할수 있는가?


할수는 있지만, 잘 할수 있는건 아니다. OOP를 잘 하려면 상당한 수고가 필요하고, 몇가지 스킬도 필요하다.


- 추상화(캡슐화).

- 상속.

- 다형성.



1. 추상화(캡슐화)


어떤 자동차가 있다고 하자. 우리는 이 자동차를 운전하고자 한다. 이 자동차를 운전하기 위해서는 자동차가 작동되는 원리를 모두 알아야 할까? 아니다. 우리는 그저 '핸들의 방향을 튼다.', '액셀을 밝으면 가속한다.', '브레이크를 밟으면 감속한다.' 정도만 알아도 된다. 우리가 알아야 할 것들은 운전을 하기 위해 꼭 필요한 것을 뿐이다. 그 이외의 것들은 자동차가 알아서 처리해준다.


=> 추상화란 필요한것들만 외부에 노출 시키고, 이외의 것들은 숨김으로써 프로그램 자체를 간략화시키는 것이다.

조금 말을 바꾸면 '프로그래머가 이 클래스에 대해 알아야 할 내용을 최소화 시키는 것.' 이라고 할 수 있다.


추상화는 '꼭 필요한 것들만 공개하는 것'이기 때문에 클래스의 보안과 프로그래밍하기 편리함을 고려하여 설계해야 한다.




2. 상속


당신이 어떠한 클래스를 만들었다고 하자. 이 클래스는 여러가지 기능을 지원해 주는 클래스다.

그러다 문든 새로운 기능을 추가하고 싶다는 생각이 들었다. 하지만, 이미 만들어진 클래스의 기능을 모두 보존한 채로 기능 하나만을 추가하고 싶었다. 그래서 이전 코드를 모두 복사 붙여넣기 한 후 새로운 기능을 하나 추가 했다. 그러다 한 가지 문제가 생겼다. 이전 클래스와 새 클래스를 완전히 다른 것으로 인식한 것이 원인이었다. 분명 클래스가 별개이긴 하지만 새로운 클래스또한 이전 기능을 모두 수행할 수 있기 때문에 구분할 이유가 전혀 없다고 생각했다. 하지만 컴파일러는 그렇게 생각하지 않은것이 문제였다.


간편하게 기능을 확장하면서, 코드의 중복을 줄이고, 컴파일러가 허락해주는 기술은 없는 것인가?


=> 상속이란, 기존의 클래스의 기능을 이어받으면서 새로운 기능을 확장하거나 기존의 기능을 수정해 새로운 클래스를 만드는 것이다.


- 상속 받는 클래스를 자식 클래스, 하위 클래스 등으로 부른다.

- 상속 하는 클래스를 부모 클래스, 상위 클래스 등으로 부른다.




3. 다형성



당신은 레이싱 시뮬레이션을 만들려고 한다. 각 차량은 브랜드와 차종, 가속력과 최고속력, 핸들링 등의 속성들이 있어 각 차종마다 값을 모두 다르게 하려 한다.

앞서 배운 상속 기능을 활용하여 가장 위에 Car 클래스를 두고, 그 밑에 FerrariCar 클래스, LamborghiniCar 클래스 등 브랜드별로 Car 클래스를 상속한 후, 하위 클래스로 차종을 달리하여 각 브랜드 차량을 상속하는 구조를 계획하고 프로그래밍을 시작했다.

그런데 생각 외로 너무많은 브랜드들과 차종이 있었고, 만들어야 하는 클래스의 수가 수백, 수천 개에 달한다는 것을 알게 되었다. 또한 이후 밸런스 조정을 위해 특정 브랜드의 차량들만 수치를 낮추는 등의 작업을 하려면 수많은 자식 클래스들의 똑같은 속성을 일일이 건드려야 한다는 단점이 있다는 것도 알게 되었다.

이럴 바에는 Car 클래스 하나만 만든 다음, 각 속성의 값을 동적으로 설정하는 것이 낫다는 생각을 했다.


동적으로 각 객체 별로 작동 방식을 다양화 하는 방법이 없을까?



=> 다형성이란, 어떤 객체의 속성이나 메서드가 상황에 따라 다르게 해석되는 것을 말한다.

=> 같은 클래스의 인스턴스라도 객체가 어떤 상태에 있느냐에 따라 동일한 속성이 달라지거나, 동일한 메서드의 결과가 달라지는 등의 성질을 지칭하는 말.


'속성은 그렇다 쳐도, 메서드는 어떻게 달라지는 거지?'라는 생각을 할 수도 있다.

Car 클래스에 printBrand란 함수가 있다고 하자. 이 객체가 람보르기니 차량이면 이 함수의결과로 'Lamborghini'가 출력되야 하고, 페러리 차량이라면 'Ferrari'가 출력되어야 할 것이다. 


객체가 다형성을 갖게 하는 방법은 단 한가지로 정형화되는 것이 아니다. 다형성을 구현하는 방법에는 수 만 가지가 있다고 해도 과언이 아니다. 객체의 속성을 참조하는 방식이 일수도 있고, 속성에 하나의 기능을 모두 위임하는 방법도 있을 수 있다.

하지만, 그 중 대표적인 방법으로는 오버라이딩(Overriding)과, 오버로딩(Overloading)이 있다.


오버라이딩 : 자식클래스에서 부모클래스의 메서드를 재정의하는 것.

오버로딩 : 다른 인자를 받는 같은 이름의 매서드를 여러 개 정의 하는 것.


같은 메서드라도 인자로 int를 넣느냐, Object를 넣느냐에 따라 다른 결과가 리턴되는 것도 있다. 이러한 것이 오버로딩이다.


※ 주의사항

- 같은 이름의 메서드들 중에서 같은 인자를 받는 메서드가 없게 해야한다.



'C∫C++' 카테고리의 다른 글

[STL] 템플릿을 이용해 Stack Calss 만들기.  (0) 2017.04.15
[C++] 함수 포인터  (0) 2017.04.14
prev 1 next