반응형

1. 클래스의 기초(클래스 = 하나의 꾸러미), 클래스의 전신은 구조체

변수 -> 배열 -> 구조체 -> 클래스
결국 여러개의 데이타를 하나로 묶는 자료구조

구조체는 변수들을 하나로 묶는 자료구조였다.
그러나, 클래스는 변수뿐만이아니라 함수또한 같이 묶을수 있는 자료구조다.
구조체는 저장하기위한 목적이였지만
클래스는 저장과 처리 이 두가지를 할 수 있다. 즉, 하나의 작은 프로그램이 된다.
구조체는 보안성이 없지만
클래스는 보안성이 있다.(딱 막아놓고 필요한애들만 접근 가능)

클래스 -> 객체..
객체들이 모이면 프로그램이 된다.

즉, 클래스는 하나의 프로그램의 단위명세서라 할 수 있다.

-------------------------------
구조체 :

struct 태그명 {
     :
   변수들
     :
};
-------------------------------
class :

class 태그명 {
      :
  변수들       - 속성
  함수들       - method
      :
};     (객체)
class 태그명 변수;
-------------------------------

public : 접근가능
private : 접근불가

class는 public이나 private를 빼고 선언하게 되면 기본으로 private로 선언이 되며
외부에서는 사용이 금지된다. 그러한 보안성을 갖고 있다.

클래스로 하나로 묶기때문에 캡슐화가 가능해지며
private로 접근을 통제하기 때문에 보안성이 생긴다.

private로 접근을 할 수 있게 해주는 역할을 가진것이
바로 method다.

class CMEM
{
   private: // 이러한 명시를 해주지 않으면 기본적으로 private로 명시된다.
            // private로 명시가 되면 외부에서 접근이 불가능해진다.
       char name[30]; // 멤버변수 : 클래스 안에 있는 변수
       int age;
  
   public:  // public으로 명시해줘야만 외부에서 접근이 가능해진다.
       void setVar(char *n, int a) { // 멤버함수 : 클래스 안에 있는 함수
       strcpy(name, n);
       age = a;
 }
 void prn() {
  cout << "이름 : " << name << ", 나이 : " << age << endl;
 }

   
※ c++ 의 구조체는 클래스와 동일하다.
   단, 차이점이 있다면 구조체는 기본값이 public인 반면 클래스는 private다.
       예제에서는 이해를 돕기위해 c언어에서의 구조체를 얘기한다.

※ 예제에서는 private에는 변수를 넣고 public에는 함수만 넣는다 이렇게
   오해할 수 있지만 사실은 누구나 접근 가능한것에는 public으로 해줘도 무관하다.


2. 상수멤버함수

c++에서 상수라는 말이 나오면 무조건 const다.

이 멤버함수에서는 어떤한 변경을 할 수 없고 그저 읽거나 출력만 할 수 있다.
이렇게 하는 이유는
이 멤버함수가 가진 기능만을 제대로 동작할 수 있도록 하는 일종의
안정장치라고 할 수 있다.

class .... {
   void func() const {
             :
}

이렇게 상수멤버함수로 만들게되면 변경할 수가 없다. 특별한 기능이
있다기보다 이렇게 변경을 하지 못하게 함으로써 프로그래밍을 더
안전하게 할 수 있는 안전장치 역할을 하게 된다.

void write() const {
  year = 2009;// 상수멤버함수로 선언해줌으로써 변수를 바꿀수 없게됐다.
  set(); // 값을 변경할 수 있는 즉 일반멤버함수 조차도 호출할 수 없다.
 // 상수멤버함수는 상수멤버함수만 호출할 수 있다.
  cout << "Title : " << title << endl;
  cout << "Year  : " << year << endl;
 }

3. 클래스의 간결화 : 클래스를 간결하게 만드는것

클래스
 선언  ->  정의  -> 실행

클래스를 선언만 하고 정의에 실제 기능들을 포함시킨뒤 그 기능을 쓸때는 정의에서 불러오는식으로
해서 클래스를 간결하게 할 수 있다.

코드형식 : void Master::set(char *t = "디폴트", int y=2000) {

Master의 함수라는것을 알수있게
반드시 Master::set() 이렇게 명시를 해줘야만 한다.(Master는 class에게 부여한 임시명칭)

클래스 안에 있는 멤버함수는 기본적으로 inline 함수가 된다.
그래서 웬만하면 길게 소스를 작성하면 안된다.
그러나 클래스의 간결화로 함수를 밖으로 빼내었을 경우
자동적으로 inline 함수가 되지 않음으로
함수 앞에 inline 이라고 명시를 해줘야만 한다.

반응형
반응형

1. 부정인수 : 인수의 개수가 정해지지 않은 인수

   메인함수에서 func() 라는 함수를 호출할때 굳이 인수를 넘겨주지 않아도
   부정인수에서 기본적으로 정해진 값이 들어가게 된다.
   이 부정인수를 사용하기 위해서 #include<stdarg.h> 라는 헤더파일을 추가해야한다.
   단, 주소는 전달하지 못하고 값만 전달할 수 있다. char, float형식은 사용할 수 없다.

     (1) va_arg()
       - 매개변수 : va_list 변수, 형(type)
       - 부정인수들은 매개변수에 대응시키고, 부정인수가 갖는 형으로 변환,
         (char, unsigned char, float형으로는 전환되지 않음)

     (2) va_list
       - 변수명 지정
       - 매개변수에 의해 부정인수의 수를 갖는다.

     (3) va_end()
       - 매개변수 : va_list 변수
       - 부정인수들을 대응시키고 인수의 수를 제거한다.

     (4) va_start()
       - 매개변수: va_list 변수
       - 매개변수를 초기화하고 부정인수의 위치를 알려준다.

사용자 삽입 이미지



2. 포인터

     (1) 참조자(Reference)
       포인터는 주소를 저장하고 그 주소를 역참조해서 값을 변경하여 여러번
       왔다갔다하는 오버헤드를 발생한다.
       그러한 포인터의 성능개선을 위해 등장한것이 참조자다.

----------(포인터연산)--
int i = 10;
int *p;
p = &i;
*p = 100

결과값 : 100
-----------------------
----------(참조자연산)--
int i = 10;
int &p = i; // i의 주소에 p도 같이 쓰는것을 의미
 // 바로 그 위치를 참조함으로써 왔다갔다하는 오버헤드를 줄이며
 // *같은 표식을 안해줌으로써 좀 더 간결할 수 있다.
p = 100;
-----------------------

사용자 삽입 이미지

       1) 포인터와 참조자의 차이점
          가. 포인터
             가) 선언과 초기화를 따로한다.
             나) 주소변경 가능
          나. 참조자
             가) 선언과 동시에 초기화
             나) 주소변경 불가능(주소를 변경해야하는 일이 생기면 포인터를 써야한다.)

     (2) Pointer와 const의 관계
       1) 포인터에 대한 상수
           const char *str = "C++ Programming";
             str[0] = 'A'; //오류
             str = "OOP Programming";  //가능
           const가 가리키고 있는것은 *str의 * 즉 값을 상수로 하겠다는 것이기 때문에
           값을 변경하려고 하면 오류가 난다.
           그러나 주소에 대해 const 한것은 아니기때문에 주소를 바꾸는것은 가능하다.

사용자 삽입 이미지

       2) 포인터상수
           char * const str = "C++ Programming";
             str[0] = 'A'; //가능
             str = "OOP Programming";  //오류
            이번엔 const가 가리키고 있는것이 str 이므로 값은 변경가능해지지만
            반대로 주소를 변경하는것은 오류가 난다.

사용자 삽입 이미지

       3) 상수에 대한 포인터 상수(1번과 2번을 합친것)
           const char * const str = "C++ Programming";
             str[0] = 'A'; //오류
             str = "OOP Programming";  //오류
            const가 *과 str 모두 가리키고 있어서 값과 주소 모두 바꿀수 없는 경우다.

     (3) 메모리할당
       1) new : 메모리 할당
          int *p = new int;  // 4바이트 만큼 메모리 할당
          int *p = new int[10]; // int가 10개 40바이트 만큼 메모리 할당
          int *p = new int(0);      // 4바이트만큼 메모리 할당하고 0으로 초기화
       2) delete : 메모리 해제
          delete p;
          단, 배열일경우(int *p = new int[10];) 이럴땐
          delete p; 할 경우 0번째인것은 해제 되지만 나머지 9개는 해제되지 않음
          그래서 delete []p; 이렇게 해제를 해야만 10개 모두 초기화가 된다.

사용자 삽입 이미지

반응형
반응형

1. 출력
    (1) cout : 기본적인 출력 객체
         1) cout << 3.12345678 << end;
            이런 소스를 작성하였을때, 기본정밀도는 소수점을 포함하여 6자리이기
            때문에 결과는 3.12346(마지막자리 반올림) 가 된다.
         2) setiosflags(ios::fixed)  : 소수점을 6자리로 고정
             cout << setiosflags(ios::fixed) << 3.12345678 << endl;
             출력은 3.123457
         3) setprecision(개수) : 원하는 소수점 개수를 출력할 수 있다.
             cout << setprecision(10) << 3.123456789 << endl;
         4) setiosflags(ios::showpoint); : 소수점 셋째자리까지 표현, 빈칸은 0으로
             cout << setiosflags(ios::showpoint);
         5) resetiosflags(ios::showpos | ios::right); : 만약 showpos, right를 설정해
             주었다면 그것을 모두 해제 시킨다.

    (2) cin : 기본적인 입력 객체
         1) cin >> name;  : 출력과 화살표의 방향이 반대 방향이다.
         2) cin은 문자열을 입력받을 경우 공백 입력시 끝으로 입력하는 약점이 있다.
             입력 : Han Dong Sun      출력 : Han
         3) cin.get() : 문자열 전문 입력 메소드. cin의 약점인 공백까지 잘 입력받는다.
             But, 고질문제가 있었으니 그것은 엔터키에 의한 버퍼문제다.
         4) cin.ignore() : cin.get()에서 문제가 생겼을때 그 자리에 추가시켜주면 문제를 해결해준다.
         5) cin.getline() : 이것역시 문자열 입력 전문 메소드로써 cin.ignore를 사용하지 않아도 된다.


2. 함수
    (1) 함수의 인자전달 방식
         1) 값에 의한 전달(Call by value)
         2) 주소에 의한 전달(Call by address)
         3) 참조에 의한 전달(Call by reference)

인자전달방식에는 이 세가지가 있는데 C언어에는 값에의한전달과 주소에의한전달
이 두가지가 있다.  C++에서 추가된것이 참조에의한전달이다. 소스코드를 보며
이해를 돕겠다.


합 구하기 Call by address
#include <iostream.h>
void hap(int, int, int, int *);

int main(void)
{
 int i=2, j=3, k=4, sum=0;
 cout << "변수의 합..." << endl;
 hap(i,j,k, &sum);
 cout << "결과 : " << sum << endl;

 return 0;
}
void hap(int a, int b, int c, int *s) {
 *s = a + b + c;
}
주소에 의해 값을 전달하는 것을 보면
sum의 주소를 넘겨주고
hap함수에서 s(sum의 값)를 연산한다.

합 구하기 Call by reference
#include <iostream.h>
void hap(int, int, int, int &);

int main(void)
{
 int i=2, j=3, k=4, sum=0;
 cout << "변수의 합..." << endl;
 hap(i,j,k, sum);
 cout << "결과 : " << sum << endl;

 return 0;
}
void hap(int a, int b, int c, int &s) {
 s = a + b + c;
}
이 소스를 쉽게말하면 sum에 s라는 별칭을 하나 줘서
간단하게 연산을 끝낼 수 있다.

가장 큰 차이점을 말하자면
주소에 의한 전달은 주소를 받아 값을 넘기고 하는 복잡한
연산과정이 있지만 참조에 의한 전달방식은 그러한 과정을
생략하여 간단하기도 하며 속도도 빠를 수 있는 장점을 갖게된다.



3. Default Argument : 매개변수에 기본값을 설정하는것
    (1) 선언
         1) void proc(int i=0, char ch='a')            
         2) proc(5) 이렇게 함수의 매개변수를 넘겨주더라도 ch값이 a로 기본적으로 설정된다.
         3) 주의점 : 일부분만 매개변수를 채울시 선언시의 매개변수 설정을 끝부터 채워줘야한다.


4. 함수의 OverLoading(중복정의)
    (1) 개념
       
똑같은 이름의 함수를 여러개 만들수 있다. 똑같은 이름의 함수를 만들 수 있으나 매개변수의 갯수,
         형식, 위치라던지의 구분을 둬야한다.
         1) 예

               void a(int i) {
               }
               void a(int i, int j) {
               }
               void a(int i, double b) {
               }
               ※ 주의할점 : 비슷한 기능을 같은 이름으로 묶어야만 편리하게 쓸수있다.


5. C코드 호출
    (1) 개념
          예전 c언어에서 사용하던 함수들을 업그레이드 하거나 컨버팅 하기 위해 사용한다.
         1) 예
               extern "C" int comp(char *, char *); // 선언
               extern "C" { // 이렇게 정의해주고
                   int comp(char *a, char *b) { // 이렇게 안에 c언어에서 쓰던 명령어들을
                   return strcmp(a,b);  // 써줌으로써 이 명령어들을 사용할 수 있다.
                   }
               }


6.inline 함수 :  내부적으로 처리하는 함수
    (1) 목적
         1)
함수를 빠르게 호출하기 위해
         2) 함수를 안전하게 쓰기 위해서(매크로 함수의 부작용을 만회하기 위해)
    (2) 개념
         함수의 내용을 메인함수에 그대로 복사해와서 처리할때 내부적으로 처리하는 함수
         내용들을 미리 복사해 놓았기때문에 속도가 빠를수밖에 없다.

     인라인함수는 짧을수록 좋다.(일반적으로 10줄정도) 왜냐하면 그대로 모두 복사해서
     사용하는것이기 때문에 함수의 길이가 너무 길게되면 오히려 배보다 배꼽이 더 커지게
     되어 속도가 더 느려질 수 있다.

     "반복문"이나 "재귀함수"일 경우 인라인함수가 무효가 되버린다.
     (=#defin(매크로함수) 실행되기전에 미리 복사되어 사용, 인라인함수와 비슷하다)

     가정하면
     int main() {
         a() {
         }
     } 이런 형태라고 보면 된다.

    쓰는방법 :
     inline void a(){ // 보통 쓰는 함수에서 inline만 붙인 형태다.
              .
              .
     }

반응형
반응형

OOP (object-oriented programming) ; 객체지향 프로그래밍

객체지향 프로그래밍(이하 줄여서 'OOP'라 칭함)은 컴퓨터 프로그램의 개발을 완전히 새로운 시각으로
바라다보는 혁명적 개념이라 할 수 있는데, 동작보다는 객체, 논리보다는 자료를 바탕으로 구성된다. 프로그램은
전통적으로 논리적인 수행 즉, 입력을 받아 처리한 다음, 결과를 내는 것이라는 생각이 지배적이었다.
또한 프로그래밍을 한다는 것은 어떻게 자료를 정의할까 보다는 어떻게 논리를 써나가는 것인가로 간주되었다.

그러나 OOP는 프로그램에서 정말 중요한 것이 논리보다는 오히려 다루고자 하는 객체라는 시각에서
접근하고 있다. 객체의 예로는, 사람(이름, 주소 등으로 묘사되는)에서부터 건물까지, 그리고 상품 판매를 위한
매장(특성이 서술되고 다뤄질 수 있는)에서부터 컴퓨터 바탕화면의 아주 작은 요소인 버튼이나 스크롤바
같은 것들까지를 모두 망라한다.
OOP에서의 첫 단계는 다루고자 하는 모든 객체와, 그것들이 서로 어떤 연관성이 있는지를 식별하는
- 흔히 데이터 모델링이라고 부르는 - 작업이다. 일단 모든 객체를 식별했으면, 객체 클래스로 일반화하고
(플라톤의 "이상적" 의자 개념이 모든 의자를 대표한다고 생각하는 식으로), 그것이 담고 있는 데이터의 종류와
그것을 다룰 수 있는 모든 논리 순서를 정의한다.

논리 순서는 메쏘드라고 부르며, 클래스의 실제 인스턴스를 하나의 "객체"라 하거나, 어떤 상황에서는 하나의
"클래스 활성체"라 한다. 객체 또는 활성체는 컴퓨터 내에서 실제로 수행되는 것이다. 메쏘드는 컴퓨터 명령어를
규정하고, 클래스 객체의 특성은 관련 데이터를 규정한다.

OOP에 사용된 개념과 규칙은 다음과 같은 중요한 이점을 제공한다.
  - 데이터 클래스 개념은 일부 또는 모든 주 클래스 특성을 공유하는 데이터 객체의 부 클래스를 정의할 수 있게
    한다. 상속이라 불리는 이 OOP 특성은 면밀한 자료 분석과 개발시간 단축, 그리고 좀더 정확한 코딩을
    보증하는 효과가 있다.

  - 클래스는 단지 관련된 데이터만 정의하기 때문에, 그 클래스의 인스턴스가 수행될 때 다른 프로그램에서
    사용하는 데이터를 (우연이라도) 건드릴 수 없게 된다. 이런 자료 숨김 특성은 높은 시스템 보안을 제공하고,
    의도하지 않은 자료의 훼손을 방지한다.
  - 클래스의 정의는 최초로 생성한 프로그램뿐 아니라 다른 OOP에 의해 재사용될 수 있다 (그리고, 이런 이유로
     네트웍에 쉽게 분산 사용된다).
  - 데이터 클래스 개념은 언어에 정의되지 않은 새로운 데이터 형식을 프로그래머가 임의로 정의할 수 있게 한다.

Smalltalk는 최초의 객체지향 프로그래밍 언어 중 하나이며, C++Java는 최근 가장 인기있는 객체지향
프로그래밍 언어이다. C++의 부분집합이라고 할수 있는 Java는 특히 기업이나 인터넷의 분산 응용프로그램에
사용되도록 설계되었다.
출처 : http://www.terms.co.kr/OOP.htm

                       C          <          C++
              구조적인 언어       객체지향언어
              절차적인 언어       Object Oriente Programming
운영체제       DOS                     Windows
             하나의 덩어리        객체들이 모인 덩어리
주인공         함수                         객체

객체지향언어의 특징 :
프로그램을 모듈화 시켜 재활용이 가능해진다.
그래서...
가장 중요한 관건은
객체를 잘 사용하는 것이다!!

함수와 객체를 극단적인 예로 차이점을 설명하자면..
함수는 한개를 실행할 수 있다면 객체는 100개를 실행할 수 있는것이다.
또한 기능역시 함수는 한개의 기능이라면 객체는 100, 1000개의 기능을 가진다.

객체(실제 존재하는 물건)
각각의 객체들은 독립적인 기능을 갖고 있으며 프로그램안에서 하나의 부분을 담당하며
기능을 수행한다. 추상적인 개념은 객체가 아니다.

:::특  징:::
   1. Inheritance(상속성)
   2. Polymorphism(다형성)
   3. 캡슐화, 추상화, 은폐성, Encapsulation

※ 객체기반언어(객체의 특징 모두 가진게 아닌 몇개만 가진 언어) - Javascript 등

1. 상속성
어떤 프로그램이 있다고 가정했을때, 다른 프로그램에서 이 프로그램을 사용할때
그저 상속을 하겠다는 명령어를 넣어주면 그 프로그램을 다른프로그램에서 사용할
수 있게된다. 즉, 재활용이 가능하다는 것 그래서 개발속도가 빨리진다. 또한 안정성또한
보장받을 수 있게된다.

2. 다형성
여러가지 모양을 가진다. 즉, 하나의 객체가 여러가지 기능을 수행할 수 있다.
사용자나 개발자 둘다에게 편리한 기능을 제공하게 된다.

3. 캡슐화
복잡한것들은 잘 포장해놓고 편리하게 사용해라. 이것은 보안성의 기능 또한 갖고있다.

위 세가지를 갖고있어야만 진정한 객체다...!!


<<<형태>>>
객체.메서드()
= 의자.옮겨라 와 같은식으로 메서드는 행동을 가리킨다. 함수가 객체안에서는 메서드다.
객체가 .을 달고 다니는 이유는 속성이나 행동들을 달고 다니기 위해 .(점)을 달고다닌다.

----------------------------------------------------------------------------------
c { printf()
     puts()

c++ {  cout  : 버퍼가 있느냐, 출력 버퍼가 있다는것은 그만큼 처리속도가 빠르다는것
(객체) cerr :  버퍼가 없느냐, 주로 에러메세지를 처리할때 쓰인다. 그때그때마다 출력

 but, 둘다 사용한다해서 별 차이는 없다. 일반적으로는 cout를 사용한다.

----------------------------------------------------------------------------------
manipulate
manipulation : 조정
setiosflags(ios::left) : 왼쪽정렬로 조정할 수 있다.
setiosflags(ios::showpos | ios::right); // showpos 양수앞에 +를 붙여준다.
resetiosflags(ios::showpos | ios::right); 설정해준 조정을 모두 해제 시키는 함수
cout << setfill('*'); // setw에 의해서 남는 공간을 특정문자로 채울수 있다.
0 : 8진수
0x : 16진수
cout << setiosflags(ios::showbase); // 0:8진수, 0x:16진수 등을 표현해준다.

반응형

+ Recent posts