Chapter 3 클래스. 최호성.

Slides:



Advertisements
Similar presentations
Power C++ 제6장 포인터와 문자열.
Advertisements

2016 ITA 1월 강의 C Programming -4일차- 포인터배열 및 이중포인터 정대진 ( )
C++ Espresso 제1장 기초 사항.
1장. 이것이 C 언어다.. 1장. 이것이 C 언어다. 1-1 C 언어의 개론적 이야기 프로그래밍 언어란 무엇인가? 컴파일이란 무엇인가? 사람과 컴파일러가 이해할 수 있는 약속된 형태의 언어 C 언어도 프로그래밍 언어 중 하나이다. 컴파일이란 무엇인가? 프로그래밍.
제 8 장  파서 생성기 YACC 사용하기.
Chapter 6 구조체.
실전 프로젝트 2 : 숫자야구 숫자 야구를 구현해보자.
제6장 객체배열과 벡터 객체 배열을 이해한다. 벡터(vector) 클래스를 사용할 수 있다.
상속.
5장. 리스트 리스트 학습목표 목록이나 도표처럼 여러 데이터를 관리할 수 있는 자료형을 추상화
8. 객체와 클래스 (기본).
C 10장. 함수의 활용 #include <stdio.h> int main(void) { int num;
C 11장. 포인터의 활용 #include <stdio.h> int main(void) { int num;
C++ Espresso 제9장 다형성.
C언어: 배열 (Arrays).
6장. printf와 scanf 함수에 대한 고찰
배열, 포인터, 참조 배열은 같은 형을 가지는 변수들의 묶음이다..
윤성우의 열혈 C 프로그래밍 윤성우 저 열혈강의 C 프로그래밍 개정판 Chapter 14. 포인터와 함수에 대한 이해.
head data link data link data link NULL a b c
윤성우의 열혈 C++ 프로그래밍 윤성우 저 열혈강의 C++ 프로그래밍 개정판 Chapter 03. 클래스의 기본.
10장 메모리 관리.
쉽게 풀어쓴 C언어 Express 제17장 동적메모리와 연결리스트 C Express.
윤성우의 열혈 C 프로그래밍 윤성우 저 열혈강의 C 프로그래밍 개정판 Chapter 02. 프로그램의 기본구성.
C 9장. 구조체 #include <stdio.h> int main(void) { int num;
7장 클래스.
18장. 헤더 파일과 구현 파일 01_ 헤더 파일과 구현 파일의 사용.
Chapter 05. 클래스 완성. chapter 05. 클래스 완성 01. 복사 생성자 복사 생성(Copy Construction) 생성될 때 자신과 같은 타입의 객체를 변수로 받아, 이 객체와 같은 값을 갖는 새로운 객체를 생성하는 것 명시적인 생성 과정뿐만.
쉽게 풀어쓴 C언어 Express 제14장 포인터 활용 C Express.
C ++ 프로그래밍 시작.
Term Project Team Member
C++ 개요 객체지향 윈도우즈 프로그래밍 한국성서대학교 유일선
스택(Stack) 김진수
13. 포인터와 배열! 함께 이해하기.
제5장 생성자와 접근제어 객체 지향 기법을 이해한다. 클래스를 작성할 수 있다. 클래스에서 객체를 생성할 수 있다.
가상함수와 추상 클래스.
Chapter 1 C와는 다른 C++. 최호성.
19. 함수 포인터와 void 포인터.
3장. 변수와 연산자. 3장. 변수와 연산자 3-1 연산자, 덧셈 연산자 연산자란 무엇인가? 연산을 요구할 때 사용되는 기호 ex : +, -, *, / 3-1 연산자, 덧셈 연산자 연산자란 무엇인가? 연산을 요구할 때 사용되는 기호 ex : +, -, *, /
Chapter 11. 배열과 포인터.
4장 자료형.
3장. 클래스의 기본.
멤버 함수인 operator+()가 실행, 또는 전역 함수인 operator+()가 실행 Point p3 = p1+p2; 에서
제8장 포인터와 동적객체 생성 포인터의 개념을 이해한다. 포인터와 관련된 연산을 이해한다.
-Part2- 제1장 1차원 배열이란 무엇인가.
6장 반복제어문 for 문 while 문 do while 문 기타 제어문.
5. 논리적 자료표현 : 구조체.
18장. 다차원 배열 그리고 포인터.
제 11장. 템플릿과 STL 학기 프로그래밍언어및실습 (C++).
3장,4장 발표 서정우.
03. 메모리 관리 C++ 프로그램에서 다룰 수 있는 메모리의 종류
4. 시간의 표현 (6장. 시간의 표현).
쉽게 풀어쓴 C언어 Express 제6장 조건문 C Express Slide 1 (of 28)
컴퓨터 프로그램은 여러 기능의 복합체이다. 라이브러리 함수와 사용자 정의 함수
제 8장. 클래스의 활용 학기 프로그래밍언어및실습 (C++).
자료구조 세미나 발표 주제: 자료구조 기초 - 1회 차: 자료구조의 정의, 기초 지식 (함수, 포인터, 레퍼런스)
컴퓨터 계측 및 실습 C++ 기초 영남대학교 기계공학부.
새로운 타입 정의하기 Defining new types
실습과제 1번 생성된 파일 basic.txt를 프로젝트 폴더에서 메모장으로 열고 내용을 확인
캡슐화 (Encapsulation) 두원공과대학 소프트웨어개발과 이 원 주.
9장. C 언어의 핵심! 함수. 9장. C 언어의 핵심! 함수 9-1 함수의 정의와 선언 main 함수 다시 보기 : 함수의 기본 형태 { } 그림 9-1.
Chapter 14. 템플릿(Template) 2
실습과제 1번 /* 1. 멤버 변수로 반경 radius를 갖고, 그 값을 모니터에 출력하는
argc, argv 의 사용방법 #include <stdio.h>
C 13장. 입출력 라이브러리 #include <stdio.h> int main(void) { int num;
17장. 포인터의 포인터.
C.
C++ 언어의 특징
3b장 구조체와 열거형 구조체의 정의 구조체 변수의 선언 구조체 초기화 및 사용 구조체 재정의 포인터를 이용해서 구조체 사용
프로그래밍 기법 최적화 프로그래밍.
Presentation transcript:

http://www.ilit.co.kr cx8537@naver.com 최호성

Chapter 3 클래스

3장의 핵심 개념 클래스 생성자와 소멸자 메서드 정적 멤버 클래스, 생성자와 소멸자, 메서드, 정적 멤버 : 함수를 멤버로 갖는 구조체의 확장이라고 생각하면 이해하기 수월하다. 생성자와 소멸자 : 클래스 객체가 생성 및 소멸할 때 ‘자동으로’ 호출되는 함수이다. 메서드 : 함수 형태로 크래스의 실제 동작과 상태를 책임진다. 정적 멤버 : 문법적으로는 정적 ‘멤버’지만 실제로는 전역 변수나 함수같은 성격을 보인다.

객체지향 프로그래밍 개요 기존 절차지향 프로그래밍 코드 HelloOOP2.c – 제작자 코드 제작자가 자료구조(구조체)와 자료를 출력할 수 있는 함수를 제공하였다. #include <stdio.h> // 제작자의 코드 typedef struct USERDATA { int nAge; char szName[32]; } USERDATA; void PrintData(USERDATA *pUser) printf("%d, %s\n", pUser->nAge, pUser->szName); }

객체지향 프로그래밍 개요 기존 절차지향 프로그래밍 코드 HelloOOP2.c – 사용자 코드 1단계 코드의 경우 화면 출력과 관련해 자료구조가 변경되면 그에 맞춰 수정될 가능성이 매우 높다. 그러나 2단계 코드는 그리 큰 차이가 없다. 그러나 2단계 코드도 자료구조와 PrintData() 함수간의 관계를 설명하는 코드는 없다. // 사용자의 코드 int main(void) { USERDATA user = { 20, "철수" }; // printf("%d, %s\n", user.nAge, user.szName); // 1단계 PrintData(&user); // 2단계 return 0; }

객체지향 프로그래밍 개요 기존 절차지향 프로그래밍 코드 HelloOOP3.c – 제작자 코드 구조체 멤버로 함수 포인터를 넣어 자료구조와 함수를 묶으려 시도한다. #include <stdio.h> // 제작자의 코드 typedef struct USERDATA { int nAge; char szName[32]; void(*Print)(struct USERDATA *); } USERDATA; void PrintData(USERDATA *pUser) printf("%d, %s\n", pUser->nAge, pUser->szName); }

객체지향 프로그래밍 개요 기존 절차지향 프로그래밍 코드 HelloOOP3.c – 사용자 코드 멤버 접근 연산자를 통해 USERDATA 구조체에 연결된 함수를 호출한다. // 사용자의 코드 int main(void) { USERDATA user = { 20, "철수", PrintData }; // printf("%d, %s\n", user.nAge, user.szName); // 1단계 // PrintData(&user); // 2단계 user.Print(&user); // 3단계 return 0; }

기존 절차지향 프로그래밍 코드 HelloOOP3.c – 사용자 코드 객체지향 프로그래밍 개요 기존 절차지향 프로그래밍 코드 HelloOOP3.c – 사용자 코드 2단계 코드에서 가장 어색한 부분은 user 객체를 통해 Print를 수행하면서 user객체의 주소를 매개변수로 전달하는 것이다. // 사용자의 코드 int main(void) { USERDATA user = { 20, "철수", PrintData }; // printf("%d, %s\n", user.nAge, user.szName); // 1단계 // PrintData(&user); // 2단계 user.Print(&user); // 3단계 user.Print(); // 4단계 return 0; }

상속을 제외하면 접근제어 지시자, 멤버 변수 및 함수 등으로 구성된다. 클래스 기본 문법 상속을 제외하면 접근제어 지시자, 멤버 변수 및 함수 등으로 구성된다. class USERDATA { public: // 멤버 변수 선언 int nAge; char szName[32]; // 멤버 함수 선언 및 정의 void Print(void) // nAge와 szName은 Print() 함수의 지역 변수가 아니다! printf("%d, %s\n", nAge, szName); } }; 접근제어 지시자 멤버 변수(데이터) 멤버 함수(메서드)

멤버 선언 및 정의 클래스는 ‘생성자’를 이용해 멤버를 초기화 할 수 있다. 생성자는 제작자가 기술하는 함수이며 자동으로 호출된다. 따라서 객체를 사용하는 사람은 초기화 문제를 고민할 필요가 없다. class CTest { public: // CTest 클래스의 '생성자 함수' 선언 및 정의 CTest() // 인스턴스가 생성되면 멤버 데이터를 '자동으로' 초기화한다. m_nData = 10; } // 멤버 데이터 선언 int m_nData; ... }; // 사용자 코드 int _tmain(int argc, _TCHAR* argv[]) CTest t;

클래스는 ‘생성자’를 이용해 멤버를 초기화 할 수 있다. 멤버 선언 및 정의 클래스는 ‘생성자’를 이용해 멤버를 초기화 할 수 있다. 초기화 목록을 이용해 멤버를 초기화 할 수 있다. class CTest { public: // CTest 클래스의 '생성자 함수' 선언 및 정의 CTest() : m_nData(10) } // 멤버 데이터 선언 int m_nData1; ... }; // 사용자 코드 int _tmain(int argc, _TCHAR* argv[]) CTest t;

멤버함수의 정의는 클래스 선언 밖에서 할 수도 있다. 멤버 선언 및 정의 멤버함수의 정의는 클래스 선언 밖에서 할 수도 있다. // 제작자 코드 class CTest { public: // CTest 클래스의 '생성자 함수' 선언 및 정의 CTest() // 인스턴스가 생성되면 멤버 데이터를 '자동'으로 초기화한다. m_nData = 10; } // 멤버 데이터 선언 int m_nData; // 멤버 함수 선언. 정의는 분리했다! void PrintData(void); }; // 외부에 분리된 멤버 함수 정의 void CTest::PrintData(void) // 멤버 데이터에 접근하고 값을 출력한다. cout << m_nData << endl;

public, protected, private 접근제어 지시자 public, protected, private public : 클래스 외부 접근(보통 멤버 접근 연산자 활용)이 모두 허용된다. protected : 클래스 외부 접근이 차단된다. 하지만 파생 클래스에서의 접근은 허용된다. private : 외부는 물론 파생 클래스에서의 접근까지 모두 차단한다. 별도의 언급이 없다면 private이다.

private 멤버는 사용자 코드에서 임의로 접근할 수 없다! 접근제어 지시자 private 멤버는 사용자 코드에서 임의로 접근할 수 없다! // 제작자 코드 class CMyData { // 기본 접근 제어 지시자는 private이다. int m_nData; public: int GetData(void) { return m_nData; } void SetData(int nParam) { m_nData = nParam; } }; // 사용자 코드 int _tmain(int argc, _TCHAR* argv[]) CMyData data; data.m_nData = 10; // 허용되지 않는다! data.SetData(10); // 허용된다. cout << data.GetData() << endl; return 0; }

객체선언시 생성자가, 소멸할 때 소멸자가 자동으로 호출된다. 생성자와 소멸자 객체선언시 생성자가, 소멸할 때 소멸자가 자동으로 호출된다. class CTest { public: CTest() cout << "CTest::CTest()" << endl; } ~CTest() cout << "~CTest::CTest()" << endl; }; int _tmain(int argc, _TCHAR* argv[]) cout << "Begin" << endl; CTest a; cout << "End" << endl; return 0; 객체가 생성되는 지점 객체가 소멸하는 지점

생성자와 소멸자 만일 클래스 객체를 전역변수로 선언한다면 그 클래스의 생성자가 main() 함수보다 먼저 호출된다. 주의사항 만일 클래스 객체를 전역변수로 선언한다면 그 클래스의 생성자가 main() 함수보다 먼저 호출된다. 생성자는 다중 정의할 수 있다. 소멸자는 다중 정의할 수 없다. main() 함수가 끝난 후에 소멸자가 호출될 수 있다. (전역변수) 생성자와 소멸자는 생략할 수 있으나 이 경우 컴파일러가 기본 생성자/소멸자를 만들어 넣는다. 만일 생성자를 다중 정의했다면 기본 생성자를 아예 생략할 수도 있다. 배열로 객체를 동적 생성했다면 반드시 배열로 삭제해야 한다.

참조자 멤버는 반드시 초기화 목록을 이용해 초기화 한다. 참조 형식 멤버 초기화 참조자 멤버는 반드시 초기화 목록을 이용해 초기화 한다. // 제작자 코드 class CRefTest { public: // 참조형 멤버는 반드시 생성자 초기화 목록을 이용해 초기화한다. CRefTest(int &rParam) : m_nData(rParam) { }; int GetData(void) { return m_nData; } private: // 참조형 멤버는 객체가 생성될 때 반드시 초기화해야 한다. int &m_nData; }; // 사용자 코드 int _tmain(int argc, _TCHAR* argv[]) int a = 10; CRefTest t(a);

생성자 다중정의 및 위임 생성자 위임은 C++11 표준부터 지원한다. 생성자에서 다른 생성자가 호출되도록 ‘위임’했다. class CMyPoint { public: CMyPoint(int x) cout << "CMyPoint(int)" << endl; ... } CMyPoint(int x, int y) // x 값을 검사하는 코드는 이미 존재하므로 재사용한다. : CMyPoint(x) private: int m_x = 0; int m_y = 0; }; 생성자에서 다른 생성자가 호출되도록 ‘위임’했다.

메서드 메서드의 종류와 특징 종류 일반 상수화 정적 가상 관련 예약어 - const static virtual this 포인터 접근 가능 불가능 일반 멤버 읽기 가능(제한적) 일반 멤버 쓰기 정적 멤버 읽기 정적 멤버 쓰기 특징 가장 보편적인 메서드 멤버 쓰기 방지가 목적 C의 전역 함수와 유사 상속 관계에서 의미가 큼.

this 포인터 작성 중인 클래스의 실제 인스턴스에 대한 주소를 가리키는 포인터 휴대폰의 시리얼 번호로 생각하면 이해하기 쉽다. 메서드가 호출될 때 호출자 코드에 선언된 인스턴스의 주소가 함께 전달되며 이 값으로 this 포인터가 초기화 된다. // 사용자의 코드 int main(void) { USERDATA user = { 20, "철수", PrintData }; // printf("%d, %s\n", user.nAge, user.szName); // 1단계 // PrintData(&user); // 2단계 user.Print(&user); // 3단계 return 0; }

하지만 이렇게 생각하면 this 포인터를 정확히 이해하기 쉽다. 다음 코드는 불가능하다. 하지만 이렇게 생각하면 this 포인터를 정확히 이해하기 쉽다. class CMyData { public: CMyData(int nParam) : m_nData(nParam) { }; void PrintData(CMyData *pData) CMyData *this = pData; cout << this->m_nData << endl; } ... }; int _tmain(int argc, _TCHAR* argv[]) CMyData a(5); a.PrintData(&a); …

멤버 변수에 읽기 접근은 가능하지만 쓰기는 허용되지 않는다. 그러나 mutable로 선언한 멤버는 쓰기 허용된다. (예외) 상수형 메서드 멤버 변수에 읽기 접근은 가능하지만 쓰기는 허용되지 않는다. 그러나 mutable로 선언한 멤버는 쓰기 허용된다. (예외) class CTest { public: ... // 상수형 메서드로 선언 및 정의했다. int GetData() const // 멤버 변수의 값을 읽을 수는 있지만 쓸 수는 없다. m_nData = 20; SetData(20); return m_nData; } int SetData(int nParam) { m_nData = nParam; } private: int m_nData = 0; };

정적 멤버는 사실상 전역 변수나 함수로 생각하는 것이 좋다. 정적 멤버는 인스턴스 선언 없이 호출할 수 있다. : 예) CTest::PrintData(); 정적 메서드는 this 포인터가 없다. 정적 변수는 반드시 선언과 정의를 분리한다. 정적 변수는 ‘동시성’(예를 들어 멀티스레드 기반 프로그램)을 지원하지 못해 문제가 발생하므로 꼭 필요한 경우에만 제한적으로 사용한다.