SlideShare a Scribd company logo
Effective C++
Chapter1. C++에 왔으면 C++의 법을 따릅시다.
Chapter2. 생성자, 소멸자 및 대입 연산자
NHNNEXT 2기
141078 정세빈
Chapter1. C++에 왔으면 C++의 법을 따릅시다.
• Item1. C++ 를 언어들의 연합체로 바라보는 안목은 필수
• Item2. #define을 쓰려거든 const, enum, inline을 떠올리자
• Item3. 낌새만 보이면 const 를 들이대 보자
• Item4. 객체를 사용하기 전에 반드시 그 객체를 초기화하자
Item1. C++ 를 언어들의 연합체로 바라보는 안목은 필수
• C++는 다중패러다임 프로그래밍 언어
=여러 하위 언어들의 연합체
• 여러 하위 언어?
절차적 프로그래밍이 기본: C언어
객체 지향 프로그래밍: 클래스, 캡슐화, 상속, 다형성, 가상 함수
함수식 프로그래밍: FC++라이브러리
일반화 프로그래밍: 템플릿, STL
메타 프로그래밍: TMP(템플릿 메타 프로그래밍)
이것들의 연합체
• 그래서?
 위의 개념을 생각하면, C++가 가지고 있는 여러 언어들의 특징을 때에
맞춰 사용하여 효율적 프로그래밍을 할 수 있다.
Item2. #define을 쓰려거든 const, enum, inline을 떠올리자
• 상수를 선언할 때
의 문제
선행 처리자가 숫자 상수로 바꾸어 버리기 때문에 컴파일러에겐
ASPECT_RATIO라는 기호가 넘어가지 않는다.
 컴파일 에러가 났을 때 ASPECT_RATIO가 아닌 1.653으로 표시해주기 때문에
헷갈릴 수 있음
디버그 시에도 기호 테이블에 들어가있지 않기 때문에 기호로 확인이 불가하다.
• 위 현상을 해결하기 위해  const로 상수 만들기
const로 만든 상수는 기호 테이블에 들어갈 뿐더러 사본은 한번만 생성되기 때
문에 #define보다 크기도 작을 수 있다.
• 클래스 멤버로 상수를 정의할 때
 #define으로는 클래스 상수를 정의할 수도 없을 뿐더러
캡슐화의 혜택도 받을 수 없다.
• 이번에도 const를 쓰면?
 클래스 상수로 쓰일 수 있다. 물론 캡슐화의 기능도
사용 가능하다. 단, 선언과 정의를 헤더에서 동시에 할 수는 없다.
Item2. #define을 쓰려거든 const, enum, inline을 떠올리자
• enum은 언제?
 특별한 경우(선언과 동시에 그 클래스 상수를 사용해야 하여 정의도 미
리 되어있어야 하는 경우)가 존재한다.
이 때, enum을 사용하여 선언과 정의를 헤더에서 동시에 하면 된다.
• enum은 그럴때만?
 enum으로 선언한 정수의 주소를 얻는 것을 막아 보안성을 높여주고,
쓸데없는 메모리 할당을 줄여준다.
또, 실용적인 이유에서 코드에 자주 쓰이니 익숙해지는게 좋다.
Item2. #define을 쓰려거든 const, enum, inline을 떠올리자
• 매크로 함수를 정의할 때
결과에 따라 달라지는 함수 호출이 문제가 된다.
• 이 때 inline을 이용하자
정규 함수의 기본 방식과 타입의 안정성까지 보장해준다.
Item2. #define을 쓰려거든 const, enum, inline을 떠올리자
• const는 일반적으로 변경이 불가한 상수로 취급할 때 쓰임
• 함수 반환값에는 항상 const를!!
안정성과 효율을 증가시키면서 에러도 줄일 수 있다.
• operator의 반환값에도 항상 const를!!
operator의 반환값에 const를 써주면
와 같은 어이없는 실수에 에러를 호출할수 있다.
Item3. 낌새만 보이면 const 를 들이대 보자
• 멤버 함수에서의 const
 “상수 객체에 대해 호출될 함수이다."를 알려주는 역할
• 이것의 장점
 인터페이스의 원활함: 해당 클래스로 만들어진 객체를 변경할 수 있는
혹은 없는 함수는 무엇인지 사용자측으로 알려준다.
 상수 객체에 대한 참조자를 넘김으로써 해당 객체를 조작할 수 있게 한
다.
Item3. 낌새만 보이면 const 를 들이대 보자
• C++의 C부분만을 사용하면 값이 초기화 된다는 보장이 없다.
• C++의 STL부분을 사용하면 그러한 보장을 해준다.
가장 좋은 방법은 모든 객체를 사용 하기 전에 항상 초기화!
Item4. 객체를 사용하기 전에 반드시 그 객체를 초기화하자
• 생성자에서의 대입
 대입으로 원하는 값으로 시작할 순 있다. (가짜 초기화)
 그러나 C++의 규칙에 의하면 객체는 데이터 멤버의 생성자의 본문이
호출 되기 전에 초기화 되어야 한다.
Item4. 객체를 사용하기 전에 반드시 그 객체를 초기화하자
• 생성자에서의 초기화
|
위와 같은 것을 멤버 초기화 리스트라고 한다.
초기화 리스트를 사용하면, 사용된 인자들이
데이터 멤버에 대한 생성자의 인자로 사용되기 때문에
바로 초기화가 가능하다.
괄호 안에 아무 인자도 넣어 주지 않아도 자동으로 각 타입의 기본값으로 초기
화를 진행한다.
초기화 순서는 데이터 멤버의 선언 순서에 영향을 받는다.
Item4. 객체를 사용하기 전에 반드시 그 객체를 초기화하자
• 비지역 정적 객체의 초기화 순서는
개별 번역 단위에서 정해진다.
-비지역 정적 객체: 전역 객체, 네임스페이스에 있는 객체,
클래스 혹은 파일에 있는 정적 객체
-번역 단위: 기본적으로 소스파일 하나(해당 소스파일에 들어있는 헤더파일도 포함)
번역단위가 다르면 비지역 정적 객체의 초기화 순서는 알 수가 없다.
번역 단위가 다른 소스에서 초기화 되지도 않은 멤버를 가져다가 사용
하는 에러가 생길 수 있다.
해결 방법: 비지역 정적 객체를 직접 가져다 쓰는 것을 방지하고 함수를 통해 해당 멤
버의 참조자를 가져다 쓰게 하면 된다.
비지역 정적 객체를 지역 정적 객체로 바꾸는 것
Item4. 객체를 사용하기 전에 반드시 그 객체를 초기화하자
Chapter2. 생성자, 소멸자 및 대입 연산자
• Item5. c++가 은근슬쩍 만들어 호출해 버리는 함수들에 촉각을 세우자
• Item6. 컴파일러가 만들어낸 함수가 필요 없으면
확실히 이들의 사용을 금해버리자
• Item7. 다형성을 가진 기본 클래스에서는
소멸자를 반드시 가상 소멸자로 선언하자
• Item8. 예외가 소멸자를 떠나지 못하도록 붙들어 놓자
• Item9. 객체 생성 및 소멸 과정 중에는
절대로 가상 함수를 호출하지 말자
• Item10. 대입 연산자는 *this의 참조자를 반환하게 하자
• Item11. operator=에서는 자기대입에 대한 처리가 빠지지 않도록 하자
• Item12. 객체의 모든 부분을 빠짐없이 복사하자.
• 어떤 멤버는 클래스 안에 선언 되어 있지 않으면 컴파일러가 기
본멤버로 자동 생성한다.
복사 생성자, 복사 대입 연산자,
소멸자 (물론 생성자도 선언이 되어있지 않다면 동일취급)
• 문제는 참조자 or 포인터를 복사하려 할 때
:C++의 참조자는 기존에 참조하고 있던 것과 다른 객체를 함께 참조 할
수 없기 때문에
이를 막기 위해 복사 생성자, 복사 대입 연산자를 직접 정의 하는
게 좋다.
(컴파일러가 기본으로 생성하여 생기는 오류를 막기 위해)
Item5. c++가 은근슬쩍 만들어 호출해 버리는 함수들에 촉각을 세우자
• Item5에서 말했듯이 클래스에 선언되지 않은 몇몇 멤버를 컴파
일러가 생성하는 경우가 있다.
• 애초에 컴파일러가 생성할 필요가 없고, 이것을 막고 싶다면
클래스의 private으로 복사 생성자와 복사 대입 연산자를 선언하고 구현
부를 비워두면 복사 생성자, 복사 대입 연산자의 사용을 막을 수 있다.
Item6. 컴파일러가 만들어낸 함수가 필요 없으면 확실히 이들의 사용을 금해버리자
• 파생 클래스를 가지고 있는 기본 클래스의 소멸자가
비 가상 소멸자이면, 대개 그 객체의 파생 클래스는
소멸되지 않는 참사가 벌어진다.
해결법은 간단하다.
기본 클래스의 소멸자앞에 virtual 키워드만 붙여주면 된다.
(내가 알기론 파생 클래스들의 소멸자에도 virtual 키워드를
붙여야 하는걸로 안다.)
• 파생 클래스가 없는 기본 클래스의 소멸자에 무작정 virtual 키
워드를 붙이는건 에러를 호출 하진 않지만, vptr(virtual table
pointer)가 늘어나면서 파일의 크기를 늘린다.
좋지 않은 행위
Item7. 다형성을 가진 기본 클래스에서는 소멸자를 반드시 가상 소멸자로 선언하자
• 순수 가상 함수를 가진 추상 클래스에서는
순수 가상 소멸자를 두면 편하다.
단, 순수 가상 소멸자의 정의를 본문에서 안해주면
링커 에러를 호출할 수도 있으니 꼭 정의해줄것
Item7. 다형성을 가진 기본 클래스에서는 소멸자를 반드시 가상 소멸자로 선언하자
• 소멸자에서 예외가 발생하면?
 예외 처리하는 도중 또 다른 소멸이 이루어 지고
또 예외가 발생한다면 예외가 겹치면서 C++에
과부화가 발생한다.
 이 경우(소멸자에서 예외가 겹치는 경우) 에는 프로그램이
정의 되지 않은 동작을 보인다.  에러
Item8. 예외가 소멸자를 떠나지 못하도록 붙들어 놓자
• 소멸자에 close선언
close가 되면 아무 문제 없지만 close에서 예외가 나온다면
또 다시 같은 문제가 재발하는 것
• try ~ catch로 close감싸기
1. close에서 예외 발생시 std::abort()로 프로그램 종료
2. 예외를 삼켜버리기 = catch문에 아무것도 하지 않음
 둘다 그다지 좋지 않은 방법
그렇다면???
Item8. 예외가 소멸자를 떠나지 못하도록 붙들어 놓자
• close() 따로 선언하기
사용자가 사용할 수 있는 close()를 만들어 사용자가 직접
소멸자를 호출하게 한다.
예외 발생시의 오류는 사용자 탓이므로 괜찮다!!
Item8. 예외가 소멸자를 떠나지 못하도록 붙들어 놓자
• 생성자에서 가상 함수는 금물
 기본 클래스 생성자는 파생 클래스 생성자보다
앞서서 진행 되는데, 만약 기본 클래스 생성자 진행중에 나온
가상 함수가 파생 클래스에 접근하게 되면
아직 초기화 되지 않은 대상을 접근 하였으므로 오류를 범하게 된다.
• 소멸자에서도 금물
 파생 클래스의 소멸자가 호출 되고 나면 C++는 해당 클래스에 들어있던 가상
함수를 없는 코드 취급하게 된다.
만약, 기본 클래스가 이 상황에서 파생 클래스의 함수에 접근 하게 된다면 이도
마찬가지 오류를 범하게 될 것이다.
Item9. 객체 생성 및 소멸 과정 중에는 절대로 가상 함수를 호출하지 말자
Item10. 대입 연산자는 *this 의 참조자를 반환하게 하자
• C++ 의 대입연산은 사슬처럼 엮일 수 있다.
 해석하면
• 위와 같은 코드를 다른 객체에도 적용 시키려면
 operator=의 정의에 return을 *this로 하여
참조자를 반환하게 하면 된다.
(+=, -=, *=도 마찬가지)
• 자기대입 : 어떤 객체가 자기 자신에 대해 대입 연산자를 적용 하는것
자기 대입 가능성이 가득한 코드
• 같은 객체가 사용될 가능성(중복참조)를 고려해야한다.
 *this 와 rhs가 같은 객체일 가능성이 있다.
그렇게 되면 삭제된 객체를 return해버리는 불상사가 발생한다.
Item11. operator= 에서는 자기대입에 대한 처리가 빠지지 않도록 하자
• operator= 앞머리에서 일치성 검사를 통해
중복 참조를 검사를 하면 된다.
• 하지만 new Bitmap()에서 예외가 난다면?
기존의 멤버가 삭제가 되어 삭제된 포인터만 가지고 있게 된다.
해결법: 기존의 멤버를 복사하여 임시 저장한 후에 new Bitmap()을 하
고, 잘 되었으면 복사했던 포인터를 삭제하여 기존의 멤버를
삭제한다.
Item11. operator= 에서는 자기대입에 대한 처리가 빠지지 않도록 하자
• 객체의 변수가 한 개라도 복사가 안되면 부분복사가 일어나게
된다.
이 때, 컴파일러는 아무 말도 해주지 않아서 문제
고로 우리는 멤버 변수 하나하나 복사할 복사 함수를 만들어 주어야
한다.
• 만약 파생 클래스를 복사할 때, 기본 클래스에 들어있는 멤버
는??
그렇다, 예상대로 컴파일러의 기본 복사 함수는 이것도 검토해주지 않는
다. 파생 클래스의 복사 함수를 만들 때 기본 클래스의 복사 함수를 호출
하는 구조로 만들어 주어야 한다.
Item12. 객체의 모든 부분을 빠짐없이 복사하자
• 복사 대입 연산자에서 복사 생성자를 호출하는 것은 금물!!
 기존의 멤버가 복사된 상태로 들어가 데이터의 손상가능성이 있다.
 그 반대(복사 생성자에서 복사 대입 연산자 호출)도 마찬가지로 위험
• 복사 대입 연산자, 복사 생성자의 다른 방법
 겹치는 멤버들을 대상으로 묶어서 별도의 멤버 함수를 만드는 것
 대체적으로 private에 선언하여 쓰고 init()이라는 이름으로 자주 쓰임
Item12. 객체의 모든 부분을 빠짐없이 복사하자

More Related Content

What's hot

Effective c++ 1
Effective c++ 1Effective c++ 1
Effective c++ 1현찬 양
 
Effective c++ 2
Effective c++ 2Effective c++ 2
Effective c++ 2현찬 양
 
이펙티브 C++ 공부
이펙티브 C++ 공부이펙티브 C++ 공부
이펙티브 C++ 공부quxn6
 
이펙티브 C++ 5,6 장 스터디
이펙티브 C++ 5,6 장 스터디이펙티브 C++ 5,6 장 스터디
이펙티브 C++ 5,6 장 스터디
quxn6
 
Effective C++ Chaper 1
Effective C++ Chaper 1Effective C++ Chaper 1
Effective C++ Chaper 1
연우 김
 
이펙티브 C++ 스터디
이펙티브 C++ 스터디이펙티브 C++ 스터디
이펙티브 C++ 스터디
quxn6
 
Effective c++ Chapter1,2
Effective c++ Chapter1,2Effective c++ Chapter1,2
Effective c++ Chapter1,2문익 장
 
이펙티브 C++ (7~9)
이펙티브 C++ (7~9)이펙티브 C++ (7~9)
이펙티브 C++ (7~9)익성 조
 
Effective c++ 정리 1~2
Effective c++ 정리 1~2Effective c++ 정리 1~2
Effective c++ 정리 1~2
Injae Lee
 
Effective c++ 챕터 2 정리
Effective c++ 챕터 2 정리Effective c++ 챕터 2 정리
Effective c++ 챕터 2 정리
연우 김
 
Effective c++ chapter 1,2 요약
Effective c++ chapter 1,2 요약Effective c++ chapter 1,2 요약
Effective c++ chapter 1,2 요약
Nam Hyeonuk
 
Effective c++ 정리 chapter 6
Effective c++ 정리 chapter 6Effective c++ 정리 chapter 6
Effective c++ 정리 chapter 6
연우 김
 
모어 이펙티브 c++ 1,2장 스터디
모어 이펙티브 c++ 1,2장 스터디모어 이펙티브 c++ 1,2장 스터디
모어 이펙티브 c++ 1,2장 스터디
quxn6
 
Effective c++chapter3
Effective c++chapter3Effective c++chapter3
Effective c++chapter3
성연 김
 
M1 2 1
M1 2 1M1 2 1
M1 2 1nexthw
 
Effective c++chapter4
Effective c++chapter4Effective c++chapter4
Effective c++chapter4
성연 김
 
Effective c++chapter1 and2
Effective c++chapter1 and2Effective c++chapter1 and2
Effective c++chapter1 and2
성연 김
 
Effective c++chapter8
Effective c++chapter8Effective c++chapter8
Effective c++chapter8
성연 김
 
Effective c++ 정리 chapter 4
Effective c++ 정리 chapter 4Effective c++ 정리 chapter 4
Effective c++ 정리 chapter 4연우 김
 

What's hot (20)

Effective c++ 1
Effective c++ 1Effective c++ 1
Effective c++ 1
 
Effective c++ 2
Effective c++ 2Effective c++ 2
Effective c++ 2
 
이펙티브 C++ 공부
이펙티브 C++ 공부이펙티브 C++ 공부
이펙티브 C++ 공부
 
5 6 1
5 6 15 6 1
5 6 1
 
이펙티브 C++ 5,6 장 스터디
이펙티브 C++ 5,6 장 스터디이펙티브 C++ 5,6 장 스터디
이펙티브 C++ 5,6 장 스터디
 
Effective C++ Chaper 1
Effective C++ Chaper 1Effective C++ Chaper 1
Effective C++ Chaper 1
 
이펙티브 C++ 스터디
이펙티브 C++ 스터디이펙티브 C++ 스터디
이펙티브 C++ 스터디
 
Effective c++ Chapter1,2
Effective c++ Chapter1,2Effective c++ Chapter1,2
Effective c++ Chapter1,2
 
이펙티브 C++ (7~9)
이펙티브 C++ (7~9)이펙티브 C++ (7~9)
이펙티브 C++ (7~9)
 
Effective c++ 정리 1~2
Effective c++ 정리 1~2Effective c++ 정리 1~2
Effective c++ 정리 1~2
 
Effective c++ 챕터 2 정리
Effective c++ 챕터 2 정리Effective c++ 챕터 2 정리
Effective c++ 챕터 2 정리
 
Effective c++ chapter 1,2 요약
Effective c++ chapter 1,2 요약Effective c++ chapter 1,2 요약
Effective c++ chapter 1,2 요약
 
Effective c++ 정리 chapter 6
Effective c++ 정리 chapter 6Effective c++ 정리 chapter 6
Effective c++ 정리 chapter 6
 
모어 이펙티브 c++ 1,2장 스터디
모어 이펙티브 c++ 1,2장 스터디모어 이펙티브 c++ 1,2장 스터디
모어 이펙티브 c++ 1,2장 스터디
 
Effective c++chapter3
Effective c++chapter3Effective c++chapter3
Effective c++chapter3
 
M1 2 1
M1 2 1M1 2 1
M1 2 1
 
Effective c++chapter4
Effective c++chapter4Effective c++chapter4
Effective c++chapter4
 
Effective c++chapter1 and2
Effective c++chapter1 and2Effective c++chapter1 and2
Effective c++chapter1 and2
 
Effective c++chapter8
Effective c++chapter8Effective c++chapter8
Effective c++chapter8
 
Effective c++ 정리 chapter 4
Effective c++ 정리 chapter 4Effective c++ 정리 chapter 4
Effective c++ 정리 chapter 4
 

Viewers also liked

Effective c++ Chapter6
Effective c++ Chapter6Effective c++ Chapter6
Effective c++ Chapter6
세빈 정
 
C언어 종결 세미나 2
C언어 종결 세미나 2C언어 종결 세미나 2
C언어 종결 세미나 2Jong Hyuck Lim
 
C언어 종결 세미나 1
C언어 종결 세미나 1C언어 종결 세미나 1
C언어 종결 세미나 1Jong Hyuck Lim
 
2015_summer_study_C언어
2015_summer_study_C언어2015_summer_study_C언어
2015_summer_study_C언어
Yonghwee Kim
 
포인터의 기초(1)
포인터의 기초(1)포인터의 기초(1)
포인터의 기초(1)
Hoyoung Jung
 
파이썬 튜토리얼 (Python tutorial)
파이썬 튜토리얼 (Python tutorial)파이썬 튜토리얼 (Python tutorial)
파이썬 튜토리얼 (Python tutorial)
민지 김
 
G+ Summer C Study 20130718(8일차)
G+ Summer C Study 20130718(8일차)G+ Summer C Study 20130718(8일차)
G+ Summer C Study 20130718(8일차)
Jake Yoon
 
AUG 리더에 지원해 보세요!!!
AUG 리더에 지원해 보세요!!!AUG 리더에 지원해 보세요!!!
AUG 리더에 지원해 보세요!!!
Atlassian 대한민국
 
디발자가 말하는 시선을 끄는 PPT
디발자가 말하는 시선을 끄는 PPT디발자가 말하는 시선을 끄는 PPT
디발자가 말하는 시선을 끄는 PPT
Jungwon An
 

Viewers also liked (9)

Effective c++ Chapter6
Effective c++ Chapter6Effective c++ Chapter6
Effective c++ Chapter6
 
C언어 종결 세미나 2
C언어 종결 세미나 2C언어 종결 세미나 2
C언어 종결 세미나 2
 
C언어 종결 세미나 1
C언어 종결 세미나 1C언어 종결 세미나 1
C언어 종결 세미나 1
 
2015_summer_study_C언어
2015_summer_study_C언어2015_summer_study_C언어
2015_summer_study_C언어
 
포인터의 기초(1)
포인터의 기초(1)포인터의 기초(1)
포인터의 기초(1)
 
파이썬 튜토리얼 (Python tutorial)
파이썬 튜토리얼 (Python tutorial)파이썬 튜토리얼 (Python tutorial)
파이썬 튜토리얼 (Python tutorial)
 
G+ Summer C Study 20130718(8일차)
G+ Summer C Study 20130718(8일차)G+ Summer C Study 20130718(8일차)
G+ Summer C Study 20130718(8일차)
 
AUG 리더에 지원해 보세요!!!
AUG 리더에 지원해 보세요!!!AUG 리더에 지원해 보세요!!!
AUG 리더에 지원해 보세요!!!
 
디발자가 말하는 시선을 끄는 PPT
디발자가 말하는 시선을 끄는 PPT디발자가 말하는 시선을 끄는 PPT
디발자가 말하는 시선을 끄는 PPT
 

Similar to Effective c++ 1,2

Effective c++ 1~8장
Effective c++ 1~8장 Effective c++ 1~8장
Effective c++ 1~8장
Shin heemin
 
Effective cpp
Effective cppEffective cpp
Effective cpp
TonyCms
 
Chapter5 ~ 6
Chapter5 ~ 6Chapter5 ~ 6
Chapter5 ~ 6Injae Lee
 
Mec++ chapter3,4
Mec++ chapter3,4Mec++ chapter3,4
Mec++ chapter3,4문익 장
 
Effective C++ Chapter 1 Summary
Effective C++ Chapter 1 SummaryEffective C++ Chapter 1 Summary
Effective C++ Chapter 1 Summary
SeungYeonChoi10
 
Effective c++ 3
Effective c++ 3Effective c++ 3
Effective c++ 3현찬 양
 
Effective java
Effective javaEffective java
Effective java
Haeil Yi
 
Effective c++ chapter5 6_ 131039 신동찬
Effective c++ chapter5 6_ 131039 신동찬Effective c++ chapter5 6_ 131039 신동찬
Effective c++ chapter5 6_ 131039 신동찬Dong Chan Shin
 
Effective c++ chapter1 2_dcshin
Effective c++ chapter1 2_dcshinEffective c++ chapter1 2_dcshin
Effective c++ chapter1 2_dcshin
Dong Chan Shin
 
More effective c++ 3주차
More effective c++ 3주차More effective c++ 3주차
More effective c++ 3주차Injae Lee
 
More effective c++ chapter1,2
More effective c++ chapter1,2More effective c++ chapter1,2
More effective c++ chapter1,2문익 장
 
Ec++ 3,4 summary
Ec++ 3,4 summaryEc++ 3,4 summary
Ec++ 3,4 summarySehyeon Nam
 
More Effective C++ 4주차
More Effective C++ 4주차More Effective C++ 4주차
More Effective C++ 4주차Injae Lee
 
Api design for c++ pattern
Api design for c++ patternApi design for c++ pattern
Api design for c++ pattern
jinho park
 
Api design for c++ ch3 pattern
Api design for c++ ch3 patternApi design for c++ ch3 pattern
Api design for c++ ch3 patternjinho park
 
More effective c++ 챕터3~4ppt
More effective c++ 챕터3~4pptMore effective c++ 챕터3~4ppt
More effective c++ 챕터3~4ppt
Injae Lee
 
More effective c++ Chap1~2
More effective c++ Chap1~2More effective c++ Chap1~2
More effective c++ Chap1~2
Injae Lee
 
Effective STL 1~4장 정리
Effective STL 1~4장 정리Effective STL 1~4장 정리
Effective STL 1~4장 정리
Shin heemin
 

Similar to Effective c++ 1,2 (20)

Effective c++ 1~8장
Effective c++ 1~8장 Effective c++ 1~8장
Effective c++ 1~8장
 
Effective cpp
Effective cppEffective cpp
Effective cpp
 
Chapter5 ~ 6
Chapter5 ~ 6Chapter5 ~ 6
Chapter5 ~ 6
 
Mec++ chapter3,4
Mec++ chapter3,4Mec++ chapter3,4
Mec++ chapter3,4
 
Effective C++ Chapter 1 Summary
Effective C++ Chapter 1 SummaryEffective C++ Chapter 1 Summary
Effective C++ Chapter 1 Summary
 
Effective c++ 3
Effective c++ 3Effective c++ 3
Effective c++ 3
 
Effective java
Effective javaEffective java
Effective java
 
1 2 1
1 2 11 2 1
1 2 1
 
Effective c++ chapter5 6_ 131039 신동찬
Effective c++ chapter5 6_ 131039 신동찬Effective c++ chapter5 6_ 131039 신동찬
Effective c++ chapter5 6_ 131039 신동찬
 
Effective c++ chapter1 2_dcshin
Effective c++ chapter1 2_dcshinEffective c++ chapter1 2_dcshin
Effective c++ chapter1 2_dcshin
 
More effective c++ 3주차
More effective c++ 3주차More effective c++ 3주차
More effective c++ 3주차
 
More effective c++ chapter1,2
More effective c++ chapter1,2More effective c++ chapter1,2
More effective c++ chapter1,2
 
Ec++ 3,4 summary
Ec++ 3,4 summaryEc++ 3,4 summary
Ec++ 3,4 summary
 
More Effective C++ 4주차
More Effective C++ 4주차More Effective C++ 4주차
More Effective C++ 4주차
 
Api design for c++ pattern
Api design for c++ patternApi design for c++ pattern
Api design for c++ pattern
 
Api design for c++ ch3 pattern
Api design for c++ ch3 patternApi design for c++ ch3 pattern
Api design for c++ ch3 pattern
 
MEC++ 5
MEC++ 5MEC++ 5
MEC++ 5
 
More effective c++ 챕터3~4ppt
More effective c++ 챕터3~4pptMore effective c++ 챕터3~4ppt
More effective c++ 챕터3~4ppt
 
More effective c++ Chap1~2
More effective c++ Chap1~2More effective c++ Chap1~2
More effective c++ Chap1~2
 
Effective STL 1~4장 정리
Effective STL 1~4장 정리Effective STL 1~4장 정리
Effective STL 1~4장 정리
 

More from 세빈 정

Gpg study3.7
Gpg study3.7Gpg study3.7
Gpg study3.7
세빈 정
 
Gpg study1.8
Gpg study1.8Gpg study1.8
Gpg study1.8
세빈 정
 
디자인 패턴(Observer, visitor)
디자인 패턴(Observer, visitor)디자인 패턴(Observer, visitor)
디자인 패턴(Observer, visitor)
세빈 정
 
소켓프로그래밍 기초요약
소켓프로그래밍 기초요약소켓프로그래밍 기초요약
소켓프로그래밍 기초요약
세빈 정
 
Pac-man
Pac-manPac-man
Pac-man
세빈 정
 
포스트모템1
포스트모템1포스트모템1
포스트모템1세빈 정
 

More from 세빈 정 (6)

Gpg study3.7
Gpg study3.7Gpg study3.7
Gpg study3.7
 
Gpg study1.8
Gpg study1.8Gpg study1.8
Gpg study1.8
 
디자인 패턴(Observer, visitor)
디자인 패턴(Observer, visitor)디자인 패턴(Observer, visitor)
디자인 패턴(Observer, visitor)
 
소켓프로그래밍 기초요약
소켓프로그래밍 기초요약소켓프로그래밍 기초요약
소켓프로그래밍 기초요약
 
Pac-man
Pac-manPac-man
Pac-man
 
포스트모템1
포스트모템1포스트모템1
포스트모템1
 

Effective c++ 1,2

  • 1. Effective C++ Chapter1. C++에 왔으면 C++의 법을 따릅시다. Chapter2. 생성자, 소멸자 및 대입 연산자 NHNNEXT 2기 141078 정세빈
  • 2. Chapter1. C++에 왔으면 C++의 법을 따릅시다. • Item1. C++ 를 언어들의 연합체로 바라보는 안목은 필수 • Item2. #define을 쓰려거든 const, enum, inline을 떠올리자 • Item3. 낌새만 보이면 const 를 들이대 보자 • Item4. 객체를 사용하기 전에 반드시 그 객체를 초기화하자
  • 3. Item1. C++ 를 언어들의 연합체로 바라보는 안목은 필수 • C++는 다중패러다임 프로그래밍 언어 =여러 하위 언어들의 연합체 • 여러 하위 언어? 절차적 프로그래밍이 기본: C언어 객체 지향 프로그래밍: 클래스, 캡슐화, 상속, 다형성, 가상 함수 함수식 프로그래밍: FC++라이브러리 일반화 프로그래밍: 템플릿, STL 메타 프로그래밍: TMP(템플릿 메타 프로그래밍) 이것들의 연합체 • 그래서?  위의 개념을 생각하면, C++가 가지고 있는 여러 언어들의 특징을 때에 맞춰 사용하여 효율적 프로그래밍을 할 수 있다.
  • 4. Item2. #define을 쓰려거든 const, enum, inline을 떠올리자 • 상수를 선언할 때 의 문제 선행 처리자가 숫자 상수로 바꾸어 버리기 때문에 컴파일러에겐 ASPECT_RATIO라는 기호가 넘어가지 않는다.  컴파일 에러가 났을 때 ASPECT_RATIO가 아닌 1.653으로 표시해주기 때문에 헷갈릴 수 있음 디버그 시에도 기호 테이블에 들어가있지 않기 때문에 기호로 확인이 불가하다. • 위 현상을 해결하기 위해  const로 상수 만들기 const로 만든 상수는 기호 테이블에 들어갈 뿐더러 사본은 한번만 생성되기 때 문에 #define보다 크기도 작을 수 있다.
  • 5. • 클래스 멤버로 상수를 정의할 때  #define으로는 클래스 상수를 정의할 수도 없을 뿐더러 캡슐화의 혜택도 받을 수 없다. • 이번에도 const를 쓰면?  클래스 상수로 쓰일 수 있다. 물론 캡슐화의 기능도 사용 가능하다. 단, 선언과 정의를 헤더에서 동시에 할 수는 없다. Item2. #define을 쓰려거든 const, enum, inline을 떠올리자
  • 6. • enum은 언제?  특별한 경우(선언과 동시에 그 클래스 상수를 사용해야 하여 정의도 미 리 되어있어야 하는 경우)가 존재한다. 이 때, enum을 사용하여 선언과 정의를 헤더에서 동시에 하면 된다. • enum은 그럴때만?  enum으로 선언한 정수의 주소를 얻는 것을 막아 보안성을 높여주고, 쓸데없는 메모리 할당을 줄여준다. 또, 실용적인 이유에서 코드에 자주 쓰이니 익숙해지는게 좋다. Item2. #define을 쓰려거든 const, enum, inline을 떠올리자
  • 7. • 매크로 함수를 정의할 때 결과에 따라 달라지는 함수 호출이 문제가 된다. • 이 때 inline을 이용하자 정규 함수의 기본 방식과 타입의 안정성까지 보장해준다. Item2. #define을 쓰려거든 const, enum, inline을 떠올리자
  • 8. • const는 일반적으로 변경이 불가한 상수로 취급할 때 쓰임 • 함수 반환값에는 항상 const를!! 안정성과 효율을 증가시키면서 에러도 줄일 수 있다. • operator의 반환값에도 항상 const를!! operator의 반환값에 const를 써주면 와 같은 어이없는 실수에 에러를 호출할수 있다. Item3. 낌새만 보이면 const 를 들이대 보자
  • 9. • 멤버 함수에서의 const  “상수 객체에 대해 호출될 함수이다."를 알려주는 역할 • 이것의 장점  인터페이스의 원활함: 해당 클래스로 만들어진 객체를 변경할 수 있는 혹은 없는 함수는 무엇인지 사용자측으로 알려준다.  상수 객체에 대한 참조자를 넘김으로써 해당 객체를 조작할 수 있게 한 다. Item3. 낌새만 보이면 const 를 들이대 보자
  • 10. • C++의 C부분만을 사용하면 값이 초기화 된다는 보장이 없다. • C++의 STL부분을 사용하면 그러한 보장을 해준다. 가장 좋은 방법은 모든 객체를 사용 하기 전에 항상 초기화! Item4. 객체를 사용하기 전에 반드시 그 객체를 초기화하자
  • 11. • 생성자에서의 대입  대입으로 원하는 값으로 시작할 순 있다. (가짜 초기화)  그러나 C++의 규칙에 의하면 객체는 데이터 멤버의 생성자의 본문이 호출 되기 전에 초기화 되어야 한다. Item4. 객체를 사용하기 전에 반드시 그 객체를 초기화하자
  • 12. • 생성자에서의 초기화 | 위와 같은 것을 멤버 초기화 리스트라고 한다. 초기화 리스트를 사용하면, 사용된 인자들이 데이터 멤버에 대한 생성자의 인자로 사용되기 때문에 바로 초기화가 가능하다. 괄호 안에 아무 인자도 넣어 주지 않아도 자동으로 각 타입의 기본값으로 초기 화를 진행한다. 초기화 순서는 데이터 멤버의 선언 순서에 영향을 받는다. Item4. 객체를 사용하기 전에 반드시 그 객체를 초기화하자
  • 13. • 비지역 정적 객체의 초기화 순서는 개별 번역 단위에서 정해진다. -비지역 정적 객체: 전역 객체, 네임스페이스에 있는 객체, 클래스 혹은 파일에 있는 정적 객체 -번역 단위: 기본적으로 소스파일 하나(해당 소스파일에 들어있는 헤더파일도 포함) 번역단위가 다르면 비지역 정적 객체의 초기화 순서는 알 수가 없다. 번역 단위가 다른 소스에서 초기화 되지도 않은 멤버를 가져다가 사용 하는 에러가 생길 수 있다. 해결 방법: 비지역 정적 객체를 직접 가져다 쓰는 것을 방지하고 함수를 통해 해당 멤 버의 참조자를 가져다 쓰게 하면 된다. 비지역 정적 객체를 지역 정적 객체로 바꾸는 것 Item4. 객체를 사용하기 전에 반드시 그 객체를 초기화하자
  • 14. Chapter2. 생성자, 소멸자 및 대입 연산자 • Item5. c++가 은근슬쩍 만들어 호출해 버리는 함수들에 촉각을 세우자 • Item6. 컴파일러가 만들어낸 함수가 필요 없으면 확실히 이들의 사용을 금해버리자 • Item7. 다형성을 가진 기본 클래스에서는 소멸자를 반드시 가상 소멸자로 선언하자 • Item8. 예외가 소멸자를 떠나지 못하도록 붙들어 놓자 • Item9. 객체 생성 및 소멸 과정 중에는 절대로 가상 함수를 호출하지 말자 • Item10. 대입 연산자는 *this의 참조자를 반환하게 하자 • Item11. operator=에서는 자기대입에 대한 처리가 빠지지 않도록 하자 • Item12. 객체의 모든 부분을 빠짐없이 복사하자.
  • 15. • 어떤 멤버는 클래스 안에 선언 되어 있지 않으면 컴파일러가 기 본멤버로 자동 생성한다. 복사 생성자, 복사 대입 연산자, 소멸자 (물론 생성자도 선언이 되어있지 않다면 동일취급) • 문제는 참조자 or 포인터를 복사하려 할 때 :C++의 참조자는 기존에 참조하고 있던 것과 다른 객체를 함께 참조 할 수 없기 때문에 이를 막기 위해 복사 생성자, 복사 대입 연산자를 직접 정의 하는 게 좋다. (컴파일러가 기본으로 생성하여 생기는 오류를 막기 위해) Item5. c++가 은근슬쩍 만들어 호출해 버리는 함수들에 촉각을 세우자
  • 16. • Item5에서 말했듯이 클래스에 선언되지 않은 몇몇 멤버를 컴파 일러가 생성하는 경우가 있다. • 애초에 컴파일러가 생성할 필요가 없고, 이것을 막고 싶다면 클래스의 private으로 복사 생성자와 복사 대입 연산자를 선언하고 구현 부를 비워두면 복사 생성자, 복사 대입 연산자의 사용을 막을 수 있다. Item6. 컴파일러가 만들어낸 함수가 필요 없으면 확실히 이들의 사용을 금해버리자
  • 17. • 파생 클래스를 가지고 있는 기본 클래스의 소멸자가 비 가상 소멸자이면, 대개 그 객체의 파생 클래스는 소멸되지 않는 참사가 벌어진다. 해결법은 간단하다. 기본 클래스의 소멸자앞에 virtual 키워드만 붙여주면 된다. (내가 알기론 파생 클래스들의 소멸자에도 virtual 키워드를 붙여야 하는걸로 안다.) • 파생 클래스가 없는 기본 클래스의 소멸자에 무작정 virtual 키 워드를 붙이는건 에러를 호출 하진 않지만, vptr(virtual table pointer)가 늘어나면서 파일의 크기를 늘린다. 좋지 않은 행위 Item7. 다형성을 가진 기본 클래스에서는 소멸자를 반드시 가상 소멸자로 선언하자
  • 18. • 순수 가상 함수를 가진 추상 클래스에서는 순수 가상 소멸자를 두면 편하다. 단, 순수 가상 소멸자의 정의를 본문에서 안해주면 링커 에러를 호출할 수도 있으니 꼭 정의해줄것 Item7. 다형성을 가진 기본 클래스에서는 소멸자를 반드시 가상 소멸자로 선언하자
  • 19. • 소멸자에서 예외가 발생하면?  예외 처리하는 도중 또 다른 소멸이 이루어 지고 또 예외가 발생한다면 예외가 겹치면서 C++에 과부화가 발생한다.  이 경우(소멸자에서 예외가 겹치는 경우) 에는 프로그램이 정의 되지 않은 동작을 보인다.  에러 Item8. 예외가 소멸자를 떠나지 못하도록 붙들어 놓자
  • 20. • 소멸자에 close선언 close가 되면 아무 문제 없지만 close에서 예외가 나온다면 또 다시 같은 문제가 재발하는 것 • try ~ catch로 close감싸기 1. close에서 예외 발생시 std::abort()로 프로그램 종료 2. 예외를 삼켜버리기 = catch문에 아무것도 하지 않음  둘다 그다지 좋지 않은 방법 그렇다면??? Item8. 예외가 소멸자를 떠나지 못하도록 붙들어 놓자
  • 21. • close() 따로 선언하기 사용자가 사용할 수 있는 close()를 만들어 사용자가 직접 소멸자를 호출하게 한다. 예외 발생시의 오류는 사용자 탓이므로 괜찮다!! Item8. 예외가 소멸자를 떠나지 못하도록 붙들어 놓자
  • 22. • 생성자에서 가상 함수는 금물  기본 클래스 생성자는 파생 클래스 생성자보다 앞서서 진행 되는데, 만약 기본 클래스 생성자 진행중에 나온 가상 함수가 파생 클래스에 접근하게 되면 아직 초기화 되지 않은 대상을 접근 하였으므로 오류를 범하게 된다. • 소멸자에서도 금물  파생 클래스의 소멸자가 호출 되고 나면 C++는 해당 클래스에 들어있던 가상 함수를 없는 코드 취급하게 된다. 만약, 기본 클래스가 이 상황에서 파생 클래스의 함수에 접근 하게 된다면 이도 마찬가지 오류를 범하게 될 것이다. Item9. 객체 생성 및 소멸 과정 중에는 절대로 가상 함수를 호출하지 말자
  • 23. Item10. 대입 연산자는 *this 의 참조자를 반환하게 하자 • C++ 의 대입연산은 사슬처럼 엮일 수 있다.  해석하면 • 위와 같은 코드를 다른 객체에도 적용 시키려면  operator=의 정의에 return을 *this로 하여 참조자를 반환하게 하면 된다. (+=, -=, *=도 마찬가지)
  • 24. • 자기대입 : 어떤 객체가 자기 자신에 대해 대입 연산자를 적용 하는것 자기 대입 가능성이 가득한 코드 • 같은 객체가 사용될 가능성(중복참조)를 고려해야한다.  *this 와 rhs가 같은 객체일 가능성이 있다. 그렇게 되면 삭제된 객체를 return해버리는 불상사가 발생한다. Item11. operator= 에서는 자기대입에 대한 처리가 빠지지 않도록 하자
  • 25. • operator= 앞머리에서 일치성 검사를 통해 중복 참조를 검사를 하면 된다. • 하지만 new Bitmap()에서 예외가 난다면? 기존의 멤버가 삭제가 되어 삭제된 포인터만 가지고 있게 된다. 해결법: 기존의 멤버를 복사하여 임시 저장한 후에 new Bitmap()을 하 고, 잘 되었으면 복사했던 포인터를 삭제하여 기존의 멤버를 삭제한다. Item11. operator= 에서는 자기대입에 대한 처리가 빠지지 않도록 하자
  • 26. • 객체의 변수가 한 개라도 복사가 안되면 부분복사가 일어나게 된다. 이 때, 컴파일러는 아무 말도 해주지 않아서 문제 고로 우리는 멤버 변수 하나하나 복사할 복사 함수를 만들어 주어야 한다. • 만약 파생 클래스를 복사할 때, 기본 클래스에 들어있는 멤버 는?? 그렇다, 예상대로 컴파일러의 기본 복사 함수는 이것도 검토해주지 않는 다. 파생 클래스의 복사 함수를 만들 때 기본 클래스의 복사 함수를 호출 하는 구조로 만들어 주어야 한다. Item12. 객체의 모든 부분을 빠짐없이 복사하자
  • 27. • 복사 대입 연산자에서 복사 생성자를 호출하는 것은 금물!!  기존의 멤버가 복사된 상태로 들어가 데이터의 손상가능성이 있다.  그 반대(복사 생성자에서 복사 대입 연산자 호출)도 마찬가지로 위험 • 복사 대입 연산자, 복사 생성자의 다른 방법  겹치는 멤버들을 대상으로 묶어서 별도의 멤버 함수를 만드는 것  대체적으로 private에 선언하여 쓰고 init()이라는 이름으로 자주 쓰임 Item12. 객체의 모든 부분을 빠짐없이 복사하자