본문 바로가기
코스웨어/10년 시스템제어

시스템제어 보고서 12번 박철민

by 알 수 없는 사용자 2010. 5. 27.
728x90
반응형


순수 가상함수


#include <iostream>

using namespace std;

class itisn
{
  public:
    virtual void test()=0;
};

class sca : public itisn
{
};

int main()
{
  sca obj1;
  obj1.test();
  return 0;
}





순수 가상함수로 정의된 test()함수는 자식클래스에서도 test()함수를 만들어줘야한다.
클래스를 동적할당 받아서 사용할시 부모클래스에 가상함수가 선언되어있다면.. 주의할점은 딱한가지.
소멸자도 가상화 시켜야한다는것이다.


#include <iostream>

using namespace std;

class itisn
{
  public:
    virtual void test()=0;
    virtual ~itisn(){}
};

class sca : public itisn
{
  public:
    void test();
};

void sca::test()
{
  cout << "sca::test()\n";
}

int main()
{
  sca obj1;
  obj1.test();
  return 0;
}




앞서 배웠기때문에.. 자세한부분은 생략 ㅋ


STL


STL에 앞서 Template (템플릿)이란 우리말로 번역하면 본뜨는 공구,형판,모형자 라는 뜻을 가지고있다.
이 세가지의 특징은 모두 만들어질 모양은 정해져 있지만 어떤 재료를 쓸지 모른다는 것이다.
즉 기능은 정해져 있지만 어떤 재료가 그 기능을 수행할지 모른다는것이 아닐까??
C++에서의 템플릿도 비슷한 뜻을 지는 문법이다

이해하기 쉽게하기위해서.. 간단한 예제한개 ㅠ

int sca(int a,int b)
{
   return a+b;
}
 

예제를 보면 인자로 들어온 a와 b를 더해 그 값을 반환하는 함수이다.
즉 위의 함수에 기능은 인자로 들어온 a와 b를 더해서 반환하는것이다.
지금은 인자값의 데이터형이나 리턴 데이터 형이 정해져 있지만 인자 값의 데이터 형과 리턴형을 바꿀수있다면 엄청편할꺼같다...
그래서 나온것이 템플릿이다!!

 
template <typename T>
T sca(T a,T b)
{
   return a+b;
}


template라는것은 이 함수(혹은 클래스)를 템플릿 화 시키겠다는 말이고 typename T라는 것은 타입이 정해져 있지않은 데이터 형 T를 선언하겠다고 보면된다.
즉 T라는 데이터 형은 타입이 정해져 있지 않은 데이터 이기 때문에 인자값에 의해서 int,float,char 심지어 string형도 된다!(오 대단)

아참.. 제일중요한것 한가지..
함수 혹은 클래스를 템플릿화하는데.. 템플릿이 정의된 함수가 끝난다면 템플릿의 수명도 끝난다.

그럼 STL은 뭘까?
STL은 표준 C++ 라이브러리의 일부분으로 Standard Template Library의 약자이다.
STL은 사람마다 조금씩 다른 정의를 내린다고 한다. 
C++의 권위자인 Scott Meyers는 STL을 "반복자를 가지고 동작하는 C++ 표준 라이브러리의 일부분"이라고 정의했다.
STL은 C++프로그래밍에서 만들어야 하는 여러 가지 자료구조 클래스와 알고리즘 등을 미리 만들어 놓은 라이브러리로 반복자라는 놈을 통해서 동작하는 라이브러리이다.

STL의 주요 구성 요소로 컨테이너, 반복자, 알고리즘, 함수자가 있다.

- 컨테이너(Container)
: 객체들을 저장하는 객체 혹은 클래스(vector, list, string, map 등)
- 반복자(iterator) : 컨테이너에 저장된 요소를 순회하고 접근하는 객체 혹은 클래스(추상화)
- 알고리즘(Algorithm) : 데이터를 다루기위한 일련의 함수(find, short, search 등)
- 함수자(Functor) : 함수처럼 동작하는 객체로 operator() 연산자를 오버로딩한 클래스의 객체

그림으로 보면 이렇게 되어있다고한다..;;



1, 컨테이너

컨테이너는 동일한 타입의 객체를 저장, 관리할 목적으로 만들어 놓은(추상화한) 클래스라고한다.
(혹은 그 컨테이너 클래스에 의해 만들어진 객체를 컨테이너라고도 한단다..)

컨테이너는 크게 두 가지로 나뉜다.

- 표준  시퀀스 컨테이너(standard sequence container) : vector, string, deque, list인 선형방식의 컨테이너
- 표준 연관 컨테이너(standard associative container) : set, multiset, map, multimap인 비선형방식의 컨테이너

그림으로 간단하게..

 컨테이너_종류(2).png


또 컨테이너는 데이터를 하나의 메모리 단위로 저장하느냐에 따라 두 가지로 나뉜다.

- 연속 메모리 기반 컨테이너(contiquous-memory) : 보통 데이터 여러개가 하나의 메모리 단위에 저장.
                                                                         배열 기반 컨테이너(array-based container)라고도 함. 
- 노드 기반 컨테이너(node-based) : 데이터 하나를 하나의 메모리 단위에 저장.

그림으로 간단하게..

 컨테이너_종류2(2).png

위 두 그림을 꼭 기억하라고한다..
컨테이너의 종류는 상당히 중요하다. 종류에 따라 여러 가지 특징(성능, 무효화, 알고리즘 사용)이 달라지기 때문이기에..

대표적인 컨테이너가 vector라고 한다.
vector의 예제...

 

#include <iostream>
#include <vector>

using namespace std;

int main()
{
  vector<char> vec;
  vec.push_back('e');
  vec.push_back('b');
  vec.push_back('a');
  vec.push_back('d');
  vec.push_back('c');
  
  for(int i=0; i < vec.size(); i++)
  {
    cout << vec[i] << "->";
  }
  cout << "NULL\n";

  return 0;
}






vector<char> 클래스와 이클래스로 생성한 객체 vec가 컨테이너라고 한다.
push_back()과 size()는 멤버 함수이다.  cout << vec[i] << "->";에서 vec[i]는 operator[]() 멤버 함수인 연산자 중복 함수이다.
컨테이너 vec는 char형 객체 'e','b','a','d','c'를 저장한다.


2. 반복자

반복자는 포인터와 비슷한 놈이라고 이해하면 편하다. 단 반복자는 컨테이너에 저장된 객체들에 접근하고 순회하는 일반화된 방법을 제공한다고 한다.
그래서 반복자는 몇 가지 특징을 가져야 함.

- 컨테이너 내부의 객체를 가리키고 접근할 수 있어야 한다.
- 컨테이너 내부의 모든 객체를 순회할 수 있어야 한다.

STL의 모든 컨테이너는 자신만의 반복자를 제공한다고 한다.

반복자는 조작 방법에 따라 다섯 가지로 나뉨.
- 입력 반복자(input iterator) : 현 위치의 데이터를 읽기만 가능한 반복자
- 출력 반복자(output iterator) : 현 위치에 데이터를 쓰기만 가능한 반복자
- 순방향 반복자(forward iterator) : 입력, 출력 반복자 기능 +  순방향으로 이동 가능한 반복자
- 양반향 반복자(bidirectional iterator) :  순방향 반복자 기능 + 역방향으로 이동 가능한 반복자
- 임의 접근 반복자(random access iterator) : 양방향 반복자 기능 + 반복자의 산술 연산이 가능한 반복자

임의 접근 반복자를 예.. vector는 임의 접근 반복자 제공한다.

 
#include <iostream>
#include <vector>

using namespace std;

int main()
{
  vector<char> vec;
  vec.push_back('e');
  vec.push_back('b');
  vec.push_back('a');
  vec.push_back('d');
  vec.push_back('c');
  
  vector<char>::iterator  it;
  
  for(it = vec.begin(); it != vec.end(); ++it)
  {
    cout << *it << "->";
  }
  cout << "NULL\n";
  cout << "반복자에 산술연산 가능" << endl;
  it = vec.begin()+1;
  cout << "vec.begin()+1 : " << *it << endl;
  it = vec.begin()+4;
  cout << "vec.begin()+4 : " << *it << endl;

  return 0;
}




vector<char>::iterator  it;처럼 반복자 클래스는 vector 클래스의 내포 클래스로 정의되어 있다. begin() 멤버 함수는 컨테이너 vec에 저장된 첫 번째 객체를 가리키는 반복자를 반환한다. end() 멤버 함수는 저장 객체의 끝을 의미하는 반복자를 리턴한다. 또 임의 접근 반복자는 vec.begin()+4처럼 반복자에 산술 연산이 가능하다.


3. 알고리즘


일반적인 용어의 알고리즘은 어떤 문제를 해결하기 수행 절차나 방법을 의미한다. 만약 '정렬'이라는 문제가 주어진다면 정렬이라는 문제를 해결하는 방법(알고리즘)은 무수히 많다(앞서 배웠던 버블정렬같은..) 또 검색, 삭제, 복사 등의 문제도 모두 수많은 해결 방법이 존재한다. 이런 해결 방법의 절차를 알고리즘이라 한다.

STL은 프로그램에서 반복되는 여러 가지 문제들의 해결 방법(알고리즘)을 일반화된 함수(템플릿 함수)로 제공한다.
대표적인 정렬 알고리즘의 예제를 보자..

 
#include <iostream>
#include <vector>
#include <algorithm> //정렬시 필요하다.

using namespace std;

int main()
{
  vector<char> vec;
  vec.push_back('e');
  vec.push_back('b');
  vec.push_back('a');
  vec.push_back('d');
  vec.push_back('c');

  cout << "vector 정렬 전\n";
  vector<char>::iterator  it;
  for(it = vec.begin(); it != vec.end(); ++it)
  {
    cout << *it << "->";
  }
  cout << "NULL\n";

  sort(vec.begin(), vec.end()); //정렬. #include <algorithm> 필요.

  cout << "vector 정렬 후 \n";
  
  for(it = vec.begin(); it != vec.end(); ++it)
  {
    cout << *it << "->";
  }
  cout << "NULL\n";

  char String[] = "String";

  cout << "문자열 정렬 \n";
  cout << String << endl;
  sort(String,String+(sizeof(String)-1));
  cout << String << endl;

  return 0;
}




모든 알고리즘은 반복자로 동작한다. sort()는 vec의 첫 번째 객체를 가리키는 반복자와 마지막을 의미하는 반복자를 인자로 받아 정렬한다.

for 루프도 for_each()알고리즘을 사용하여 작성할 수 있다.

 
#include <iostream>
#include <vector>
#include <algorithm>

using namespace std;

void Print(const char& n)
{
    cout << n <<"->";
}

int main()
{
  vector<char> vec;
  vec.push_back('e');
  vec.push_back('b');
  vec.push_back('a');
  vec.push_back('d');
  vec.push_back('c');
  
  cout << "vector 정렬 전\n";
  for_each(vec.begin(), vec.end(), Print);
  cout << "NULL" << endl;

  sort(vec.begin(), vec.end()); //정렬. #include <algorithm> 필요.

  cout << "vector 정열 후 \n";
  for_each(vec.begin(), vec.end(), Print);
  cout << "NULL" << endl;

  return 0;
}



for_each()는 vec.begin() 반복자부터 vec.end()반복자까지 vec 컨테이너에 저장된 모든 객체를 인자로 Print함수를 호출한다.
사실 for_each() 알고리즘은 아직잘 모르겠다;;;;; 

for_each()는 아래와 비슷하게 정의되어 있다고 한다...

 
template<class _InIt,class _Fn1>
inline  _Fn1 for_each(_InIt _First, _InIt _Last, _Fn1 _Func)
{  
    for (; _First != _Last; ++_First)
        _Func(*_First);
    return (_Func);
}


ios_base 클래스


ios_base 클래스는 입출력과 관련된 여러 가지 상수나 플래그들을 가진다.

 
#include <iostream>

using namespace std;

int main()
{
  ios_base::fmtflags Old;
  
  cout << true << endl;
  cout.setf(ios_base::boolalpha);
  cout << true << endl;
  cout << boolalpha << true << endl; 
  cout.unsetf(ios_base::boolalpha); //해제
  cout << "*******************************\n";
//**********************************************  
  cout << 10 << endl;
  cout << -10 << endl;
  cout.setf(ios_base::showpos);
  cout << 10 << endl;
  cout << -10 << endl;
  cout << showpos << 10 << endl; 
  cout.unsetf(ios_base::showpos); //해제
  cout << "*******************************\n";
//**********************************************
  cout << 99 << endl;
  Old = cout.setf(ios_base::hex,ios_base::basefield);
  cout << 99 << endl;
  cout << hex << 99 << endl;
  cout << dec << 99 << endl;
  cout.setf(Old, ios_base::basefield); //해제
  cout << "*******************************\n";
//**********************************************
  cout.width(10);            //단발성
  cout << 100 << endl;
  cout.fill('*');
  cout.width(10);
  cout << 100 << endl;
  cout << "*******************************\n";
//**********************************************
  cout << true << endl;
  cout << 10 << endl;
  
  return 0;
}






showpos

수 앞에 양의 부호를 추가한다.

showbase

숫자값과 밑수를 보여준다.

예를 들어, 만일 변경된 진수가 16진수라면, 1F 0x1F로 출력될 것이다.

uppercase

문자들은 대문자로 출력된다

showpoint

필요하든 않든 모든 실수를 출력할 때 소수점과 뒤쪽에 0을 추가하도록 한다.

boolalpha

Inserts and extracts bool type in alphabetic format.

unitbuf

C++ 입출력 시스템은 각 출력 연산 후에 출력 스트림을 비우도록 한다

internal

가운데 정렬출력

left

좌측정렬 출력

right

우측정렬 출력

dec

10진수출력

hex

16진수출력

oct

8진수출력

fixed

6자리 10진수가 출력된다.

scientific

실수값을 과학 계산 표시로 출력한다.

Skipws

스트림에 입력될 때 선행의 공란 문자(스페이스, , 뉴라인) 등이 무시된다


Formatting
- unseft : Format flag 무효화 설정.
- precision : 소수점 이하 자리 설정(Get/Set)
- width : Output stream의 길이지정
- flags : Format flat 설정(Get/Set)
- setf : Format 유효화 설정.




728x90