SlideShare une entreprise Scribd logo
1  sur  49
More Effective C++ 정리
131054 이인재
항목 1 : 포인터와 참조자를 구분
하자
1. 포인터는 “*” 와 “->”연산자 사용
2. 참조자는 “.”을 사용
3. 어떤 객체를 참조하는 부분에 꼭 객체가 있지 않을
경우도 있다면? 포인터를 써야한다
4. 반대로 객체가 반드시 있다고 확신할 수 있다면? 참
조자를 써야한다.
참조자
1. 참조자에 NULL 값을 억지로 넣는 코드는 무시!( 해서는
절대 안됨)
참조자
1. 참조자는 반드시 선언과 동시에 초기화 필요
포인터
1. 포인터는 NULL객체가 올 수 있고, 선언과 동시에 초기
화 할 필요가 없다.
2. 포인터는 NULL값을 항상 체크해야 한다
참조자와 포인터의 차이
1. 참조자는 가리키는 대상을 바꿀 수 없다.
2. 처음 초기화 한 대상만을 계속 참조
참조자와 포인터의 차이
1. 포인터는 가리키는 대상을 변경할 수 있다
포인터와 참조자는 어디에?
1. 포인터를 써야 하는 경우는 가리킬 객체의 주소가
없을 수도 있을 때
2. 하나의 변수를 가지고 여러 개의 객체를 바꾸어 참
조해야 할 때( 포인터에는 주소값을 바꾸어 대입하
면 된다)
3. 참조자는 참조할 포인터가 처음부터 끝까지 존재하
고, 참조하는 대상 객체를 바꿀 필요가 없을 때
반드시 참조자를 써야하는 경우
1. 연산자 함수를 구현할 때
2. Operator[]이 가장 흔한 예시, 이 연산자는 대입 연산
자의 좌변으로 쓸 수 있는 값을 반환해 주도록 만드
는 것이 보통
항목 1 정리
1. 참조하고자하는 어떤 객체를 미리 알고있고, 이 객
체를 다른 객체로 바꿀 일도 없고, 널 값도 되지않는
다는 보장이 있을때는? -> 참조자
2. 그 이외에는 무조건 포인터
항목 2 : 가능한 C++ 스타일의 캐
스트를 즐겨 쓰자
1. go to 문과 함께 가장 기피해야할 키워드가 “캐스트”
2. C스타일의 캐스트는 어떤 타입을 다른 타입으로 아무 생
각 없이 바꾸어줌 -> 위험
3. C스타일의 캐스트를 써서 문제가 생길경우 프로그래머
입장에서 발견하기가 힘들다
4. C++스타일의 타입 캐스팅은 (C++ static_cast예시)
(타입) 표현식 이 아니라
static_cast<타입>(표현식) 으로 쓴다.
-> C++스타일의 캐스트가 더욱 잘 눈에 띈다.
C 스타일 캐스트
C++ 스타일 캐스트
const_cast
1. 상수성이나 휘발성을 제거하는데 쓰이는 캐스팅
const_cast는 언제 쓰이나?
1. const_cast를 써서 상수성을 제거 가능
dynamic_cast
1. 상속 계층 관계를 가로지르거나 하향시킨 클래스타입 캐스팅
2. 기본클래스의 객체에 대한 포인터나 참조자의 타입을 파생 클래스,
혹은 형재 클래스의 타입으로 변환해 줌
3. 캐스팅 실패시 NULL값 리턴
dynamic_cast는 언제 쓰이나
?
1. Animal 포인터를 Cat포인터 타입으로 다운캐스팅 해준
다
다운 캐스팅의 제약 조건
1. 상속 계층 구조를 오갈 때에만 사용해야
함
2. 가상 함수가 없는 타입에는 적용할 수 없
음
3. 상수성 제거에 쓸 수 없음
reinterpret_cast
1. 가장 흔한 용도는 함수 포인터 타입을 서로 바꾸는 것
2. 이 연산자가 적용된 후의 변환 결과는 거의 항상 컴파일
러에 따라 다르게 정의
주의점
1. 함수 포인터의 캐스팅은 소스의 이식성
을 떨어뜨림
2. 이런 캐스팅은 잘못된 결과를 낼 수도 있
음
항목2 정리
1. C++스타일이 C스타일의 캐스트보다 더
보기에 좋고, 읽어내기에도 쉽다
2. 다른 프로그래머에게 확실한 의미와 인
식성을 선사할 수 있음
3. 아무리 C++스타일의 캐스트라고 해도
최대한 피해야 하는 것이 권장사항
항목 3 : 배열과 다형성은 같은 수
준으로 놓고 볼 것이 아니다
1. 상속성이 주는 가장 중요한 혜택 중 하나는, 기본 클
래스 객체의 포인터나 참조자를 통해 파생 클래스
객체를 조작할 수 있다는 점
2. 이렇게 쓰이는 포인터나 참조자를 가리켜 “ 다형성
을 가지고 있다”라고 말함
3. 파생 클래스 객체의 배열을 기본 클래스 포인터나
참조자를 통해 조작하는 것도 됨
다형성과 포인터 산술 연산은 간단히
섞이지 않음
1. 배열이 삭제될 때, 배열의 각 요소 객체에 대해 소멸자가 호출
2. 기본 클래스 포인터를 통해 파생 클래스 객체의 배열을 삭제한
결과는 “정의되지 않음”
3. 어떤 구체 클래스부터 또 다른 구체 클래스를 파생시키는 일만
없으면, 객체의 배열을 다형적으로 조작하는 실수는 별로 하지
않는다
항목3 정리
1. 기본 클래스 포인터를 통해 파생 클래스
객체의 배열을 삭제한 결과는 “정의되지
않았다”
2. 다형성과 산술 연산은 간단히 섞이는 것
이 아님
3. 배열과 다형성은 물과 기름의 관계
항목 4 : 쓸데 없는 기본 생성자는
그냥 두지 말자
1. 생성자는 객체를 초기화하는 역할
2. 조심해야할 점은 어떤 객체의 경우 외부 정보 없이
는 완전한 초기화를 수행할 수 없는 경우가 있음 ->
클래스 설계에 따라 사원클래스에 ‘사원번호’가 없다
든지 이런 정보들이 없으면 초기화할 수 없음
기본 생성자가 없을때 문제점
1
1. 기본 생성자가 없으면 배열을 생성할 때 , 배열의 요소
로 들어가는 객체에 대해 생성자 매개변수를 지정할 수
없기때문에 배열 생성 불가능
생성자 매개변수를 입력하여 해
결
1. 생성자 매개변수를 직접 입력
포인터 배열을 이용하여 해결
1. 포인터의 배열을 만들어 각각이 하나의 객체를 가리키
도록 만들어줌
포인터 배열 사용의 문제점
1. 배열 내의 모든 포인터가 가리키는 객체를 삭제해야 함
-> 그렇지 않으면 메모리 누수
2. 필요한 메모리 사용량이 늘어남
-> 객체를 담을 메모리 공간 이외에 포인터를 담을 공간
또한 필요
기본 생성자가 없을때 문제점
21. 템플릿 기반의 컨테이너 클래스와 연계할 수 없다
2. 컨테이너 클래스를 인스턴스화하기 위해서는 템플릿 매개변
수로 들어가는 타입이 기본 생성자를 가지고 있어야 하기 때
문.
3.
-> 기본 생성자가 없는 클래스를 템플릿 매개변수로 쓸 수 없
음!
항목 4 정리
1. 쓸 데 없는 기본 생성자는 클래스의 효율에 걸림돌
-> 멤버 함수들은 클래스의 멤버데이터가 제대로 초기화
되었는지를 검사해야하기 때문에 실행속도 느려짐
2. 추가된 검사 코드의 크기만큼 실행 파일이 커짐
3. 이를 막기위해 생성자가 객체의 멤버 데이터를 확실히
초기화 해야함
4. 특별한 상황이 아니면 기본생성자를 피해야 함
항목 5 : 사용자 정의 타입변환 함
수에 대한 주의를 놓지 말자
1. 암시적 타입변환을 수행하기 위해, 컴파일러가 사용
하는 함수를 제공할 것인가 말 것인가의 여부를 결
정할 수 있다
2. 컴파일러가 사용할 수 있는 타입변환 함수는 단일
인자 생성자와 암시적 타입변환 연산자이다
3. 단일 인자 생성자는 인자를 하나만 받아서 호출되는
생성자
4. 암시적 타입 연사자는 일종의 멤버 함수
explicit키워드를 활용하자
1. 암시적 타입변환의 문제를 막
기위해 만들어 진것
2. 사용법도 상당히 단순
3. 앞에 키워드를 붙여주면 된다
4. 매개변수와 호출이 명확할 때
에만 이 생성자를 호출
항목 5 정리
1. explicit를 사용하여 암시적 타입변환을 막을 수 있음
2. explicit를 지원하지 않는 컴파일러라면 단일 인자 생
성자를 사용하지 않는 다른 방법을 사용해야 함
3. 컴파이러가 암시적 타입변환을 하도록 내버려두면
득보다 실이 많음
항목 6 : 증가 및 감소 연산자의
전위/후위 형태를 반드시 구분하
자
1. 증감 연산자의 전위 형태와 후위 형태는 서로 다른
타입을 반환
2. 전위 형태는 참조자 타입을 반환하고, 후위 형태는
const 객체 타입을 반환
3. 전위 연산자는 값을 변경시키고 값을 사용
4. 후위 연산자는 값을 사용하고 값을 변경
전위, 후위 연산의 차이
1. C++ 스펙에 전위/ 후위 연산자의 구현을 보면 전위는 값
을 변한 뒤 값을 사용하고, 후위는 값을 사용하고 값을
변경
후위 연산은 왜 Const가 아닌 객
체를 반환하는 것을 꺼려할까?
1. 기본 제공 타입에 대한 증가연산자의 동작과 맞지
않음
int 를 예로 들면
int i =1;
i++++;로 쓰지 않는다(에러)
2. 사용자는 절대로 이런 괴상한 동작을 웃고 넘기지
않는다
-> 프로그래머 입장에서 직관적이지 않고 애매하다
후위연산과 전위연산의 효율
1. 후위 연산은 반환값으로 쓰기 위한 임시객체를 만들
고, 지역 변수로서 생겼다가 없어지는 임시 객체를
만듦
2. 전위연산자는 이런 임시 객체를 사용하지 않음
->후위 연산보다 전위연산이 더 효율적
3. 두 연산자는 반환타입을 제외하면 하는 일이 같음
항목 6 정리
1. 함사용자 정의 타입을 가지고 작업할 때에는 되도록
전위 연산자를 사용할 것
2. 전위, 후위 연산자에 따라서 반환타입이 어떻게 되
는지 알아야 함
항목 7 : && , || 혹은 , 연산자는
오버로딩 대상이 절대로 아니다
1. C와 C++은 복합적인 불린 표현식을 평가할 때 단축
평가 처리를 할 수 있음, 표현식의 일부가 참 혹은 거
짓이란 것이 판명되면, 그 이후의 표현식은 스킵
char * p;
if( (p != 0) && (strlen(p) >10 ) … )
에서 p가 널 포인터이면 strlen은 호출하지 않고 종
료
_________________________________________
_
if( (index < lowerBound) || (index > upperBound ))
에서 index < lowerBound dㅣ면 뒤에 조건식은 스킵
&& 연산자
1. &&을 사용자가 임의로 변경 가능
2. &&을 변경한다는 것은 컴파일러가 다음과 같이 해석하게 한다는 것
3. 함수 호출이 이루어 질 때 모든 매개변수를 평가
4. 평가 순서를 명확하게 알지 못해 어떤 것을 먼저 처리할 것인지 알 수
없음
(단축평가는 왼쪽에서 오른쪽으로 표현식 평가)
|| 연산자도 마찬가지이다!
&&, ||를 오버로딩 한다는 것은 단축평가에 문제가 생길 수 있음!
, 연산자
1. 쉼표 연산자는 쉼표의 왼쪽에 있는 표현식을 먼저 평가
하고, 그 다음에 오른쪽에 있는 표현식을 평가하면서 진
행
도 오버로딩이 가능 하다, 하지만 오버리등을 하면 원래의 동작과
항목 7 정리
1. && 와 || 그리고 , 연산자는 함부로 오버로딩 하면 안
된다
-> 단축평가 순서 및 동작방식에 문제가 발생할 수
있음
2. 오버로딩이 가능한 연산자라도 연산자 오버로딩의
목적을 이해하고 써야 함
항목 8 : new 와 delete의 의미를
정확히 구분하고 이해하자
1. string *ps = new string(“memory Management”);
new연산자의 동작은 2단계
요청한 타입의 객체를 담을 수 있는 크기의 메모리 할
당
할당된 메모리에 객체 초기화를 수행
2. operator new 함수는
void * operator new(size_t size);
이 함수의 반환 타입은 void*이다.
new 연산자가 하는 일
1. new연자에서 생성자 호출 단계는 프로그래머가 손댈 수
없음, 컴파일러만이 가능
메모리 지정 new
1. 할당받은 미초기화 메모리가 있고, 객체 형태로 만들고
싶을 때 쓰는 방법
객체를 buffer로 지정되는 메모리에 생성한 후에 그 포인터를 반환
객체 삭체와 메모리 해제
1. 메모리 누수를 막기 위해, 할당한 메모리는 반드시 해제
2. 기본적으로 delete 연산자를 사용
3. operator delete 함수 이용
객체의 배열 메모리 해제
1. 단일 객체 해제와 달리 객체 배열의 해제는 operator
new[]를 호출
항목 8 정리
1. new와 delete 연산자는 C++에서 기본적으로 제공되
는 함수
2. 이 연산자가 내부적으로 사용하는 메모리 할당 함수
및 해제 함수는 수정 가능
3. 하지만 이 연산자의 동작을 수정하는 것은 많은 위험
감수 -> 어차피 하는 일은 C++언어에서 고정되어 있
음

Contenu connexe

Tendances

M1 2 1
M1 2 1M1 2 1
M1 2 1
nexthw
 
More effective c++ 1
More effective c++ 1More effective c++ 1
More effective c++ 1
현찬 양
 
Effective c++ 4
Effective c++ 4Effective c++ 4
Effective c++ 4
현찬 양
 
The C++ Programming Language 5장 포인터, 배열, 구조체
The C++ Programming Language 5장 포인터, 배열, 구조체The C++ Programming Language 5장 포인터, 배열, 구조체
The C++ Programming Language 5장 포인터, 배열, 구조체
해강
 
NHNNEXT 개경프14 Subway Rocket Team Study 3rd C++
NHNNEXT 개경프14 Subway Rocket Team Study 3rd C++NHNNEXT 개경프14 Subway Rocket Team Study 3rd C++
NHNNEXT 개경프14 Subway Rocket Team Study 3rd C++
Min-soo Park
 
More effective c++ chapter1,2
More effective c++ chapter1,2More effective c++ chapter1,2
More effective c++ chapter1,2
문익 장
 
Swift세미나(속성(properties), 메소드(method))
Swift세미나(속성(properties), 메소드(method))Swift세미나(속성(properties), 메소드(method))
Swift세미나(속성(properties), 메소드(method))
경원 정
 
Effective c++ 2
Effective c++ 2Effective c++ 2
Effective c++ 2
현찬 양
 
Effective c++ 1
Effective c++ 1Effective c++ 1
Effective c++ 1
현찬 양
 
Effective c++ Chapter1,2
Effective c++ Chapter1,2Effective c++ Chapter1,2
Effective c++ Chapter1,2
문익 장
 
Ruby - 6th (루비 6장 변수와 식)
Ruby - 6th (루비 6장 변수와 식)Ruby - 6th (루비 6장 변수와 식)
Ruby - 6th (루비 6장 변수와 식)
재영 이
 
More effective c++ 2
More effective c++ 2More effective c++ 2
More effective c++ 2
현찬 양
 
More effective c++ 3
More effective c++ 3More effective c++ 3
More effective c++ 3
현찬 양
 

Tendances (20)

이펙티브 C++ 5,6 장 스터디
이펙티브 C++ 5,6 장 스터디이펙티브 C++ 5,6 장 스터디
이펙티브 C++ 5,6 장 스터디
 
Effective c++ 1,2
Effective c++ 1,2Effective c++ 1,2
Effective c++ 1,2
 
M1 2 1
M1 2 1M1 2 1
M1 2 1
 
More effective c++ 1
More effective c++ 1More effective c++ 1
More effective c++ 1
 
[SwiftStudy 2016] 3장. 함수
[SwiftStudy 2016] 3장. 함수[SwiftStudy 2016] 3장. 함수
[SwiftStudy 2016] 3장. 함수
 
effective c++ chapter 3~4 정리
effective c++ chapter 3~4 정리effective c++ chapter 3~4 정리
effective c++ chapter 3~4 정리
 
Effective c++ 4
Effective c++ 4Effective c++ 4
Effective c++ 4
 
The C++ Programming Language 5장 포인터, 배열, 구조체
The C++ Programming Language 5장 포인터, 배열, 구조체The C++ Programming Language 5장 포인터, 배열, 구조체
The C++ Programming Language 5장 포인터, 배열, 구조체
 
NHNNEXT 개경프14 Subway Rocket Team Study 3rd C++
NHNNEXT 개경프14 Subway Rocket Team Study 3rd C++NHNNEXT 개경프14 Subway Rocket Team Study 3rd C++
NHNNEXT 개경프14 Subway Rocket Team Study 3rd C++
 
[SwiftStudy 2016] 2장. Swift 타입 파트 1
[SwiftStudy 2016] 2장. Swift 타입 파트 1[SwiftStudy 2016] 2장. Swift 타입 파트 1
[SwiftStudy 2016] 2장. Swift 타입 파트 1
 
More effective c++ chapter1,2
More effective c++ chapter1,2More effective c++ chapter1,2
More effective c++ chapter1,2
 
Swift세미나(속성(properties), 메소드(method))
Swift세미나(속성(properties), 메소드(method))Swift세미나(속성(properties), 메소드(method))
Swift세미나(속성(properties), 메소드(method))
 
Effective c++ 2
Effective c++ 2Effective c++ 2
Effective c++ 2
 
Effective c++ 1
Effective c++ 1Effective c++ 1
Effective c++ 1
 
Effective c++ Chapter1,2
Effective c++ Chapter1,2Effective c++ Chapter1,2
Effective c++ Chapter1,2
 
Ruby - 6th (루비 6장 변수와 식)
Ruby - 6th (루비 6장 변수와 식)Ruby - 6th (루비 6장 변수와 식)
Ruby - 6th (루비 6장 변수와 식)
 
Java generics
Java genericsJava generics
Java generics
 
More effective c++ 2
More effective c++ 2More effective c++ 2
More effective c++ 2
 
More effective c++ 3
More effective c++ 3More effective c++ 3
More effective c++ 3
 
5 6 1
5 6 15 6 1
5 6 1
 

Similaire à More effective c++ Chap1~2

Ec++ 3,4 summary
Ec++ 3,4 summaryEc++ 3,4 summary
Ec++ 3,4 summary
Sehyeon Nam
 
Mec++ chapter3,4
Mec++ chapter3,4Mec++ chapter3,4
Mec++ chapter3,4
문익 장
 
Effective c++ 3
Effective c++ 3Effective c++ 3
Effective c++ 3
현찬 양
 
More Effective C++ 4주차
More Effective C++ 4주차More Effective C++ 4주차
More Effective C++ 4주차
Injae Lee
 
M5 1 1
M5 1 1M5 1 1
M5 1 1
nexthw
 

Similaire à More effective c++ Chap1~2 (20)

Effective c++ 1~8장
Effective c++ 1~8장 Effective c++ 1~8장
Effective c++ 1~8장
 
Effective c++ chapter 1,2 요약
Effective c++ chapter 1,2 요약Effective c++ chapter 1,2 요약
Effective c++ chapter 1,2 요약
 
Effective cpp
Effective cppEffective cpp
Effective cpp
 
More effective c++ chapter1 2_dcshin
More effective c++ chapter1 2_dcshinMore effective c++ chapter1 2_dcshin
More effective c++ chapter1 2_dcshin
 
More effective c++ 챕터3~4ppt
More effective c++ 챕터3~4pptMore effective c++ 챕터3~4ppt
More effective c++ 챕터3~4ppt
 
MEC++ 3,4
MEC++ 3,4MEC++ 3,4
MEC++ 3,4
 
Ec++ 3,4 summary
Ec++ 3,4 summaryEc++ 3,4 summary
Ec++ 3,4 summary
 
Effective c++ 정리 1~2
Effective c++ 정리 1~2Effective c++ 정리 1~2
Effective c++ 정리 1~2
 
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
 
Mec++ chapter3,4
Mec++ chapter3,4Mec++ chapter3,4
Mec++ chapter3,4
 
Effective c++ 3
Effective c++ 3Effective c++ 3
Effective c++ 3
 
Python 이해하기 20160815
Python 이해하기 20160815Python 이해하기 20160815
Python 이해하기 20160815
 
디자인패턴 1~13
디자인패턴 1~13디자인패턴 1~13
디자인패턴 1~13
 
Head first디자인패턴 1~13_희민_호준
Head first디자인패턴 1~13_희민_호준Head first디자인패턴 1~13_희민_호준
Head first디자인패턴 1~13_희민_호준
 
More Effective C++ 4주차
More Effective C++ 4주차More Effective C++ 4주차
More Effective C++ 4주차
 
연산자 오버로딩
연산자 오버로딩연산자 오버로딩
연산자 오버로딩
 
3 4 1
3 4 13 4 1
3 4 1
 
2013 C++ Study For Students #1
2013 C++ Study For Students #12013 C++ Study For Students #1
2013 C++ Study For Students #1
 
M5 1 1
M5 1 1M5 1 1
M5 1 1
 

More effective c++ Chap1~2

  • 1. More Effective C++ 정리 131054 이인재
  • 2. 항목 1 : 포인터와 참조자를 구분 하자 1. 포인터는 “*” 와 “->”연산자 사용 2. 참조자는 “.”을 사용 3. 어떤 객체를 참조하는 부분에 꼭 객체가 있지 않을 경우도 있다면? 포인터를 써야한다 4. 반대로 객체가 반드시 있다고 확신할 수 있다면? 참 조자를 써야한다.
  • 3. 참조자 1. 참조자에 NULL 값을 억지로 넣는 코드는 무시!( 해서는 절대 안됨)
  • 4. 참조자 1. 참조자는 반드시 선언과 동시에 초기화 필요
  • 5. 포인터 1. 포인터는 NULL객체가 올 수 있고, 선언과 동시에 초기 화 할 필요가 없다. 2. 포인터는 NULL값을 항상 체크해야 한다
  • 6. 참조자와 포인터의 차이 1. 참조자는 가리키는 대상을 바꿀 수 없다. 2. 처음 초기화 한 대상만을 계속 참조
  • 7. 참조자와 포인터의 차이 1. 포인터는 가리키는 대상을 변경할 수 있다
  • 8. 포인터와 참조자는 어디에? 1. 포인터를 써야 하는 경우는 가리킬 객체의 주소가 없을 수도 있을 때 2. 하나의 변수를 가지고 여러 개의 객체를 바꾸어 참 조해야 할 때( 포인터에는 주소값을 바꾸어 대입하 면 된다) 3. 참조자는 참조할 포인터가 처음부터 끝까지 존재하 고, 참조하는 대상 객체를 바꿀 필요가 없을 때
  • 9. 반드시 참조자를 써야하는 경우 1. 연산자 함수를 구현할 때 2. Operator[]이 가장 흔한 예시, 이 연산자는 대입 연산 자의 좌변으로 쓸 수 있는 값을 반환해 주도록 만드 는 것이 보통
  • 10. 항목 1 정리 1. 참조하고자하는 어떤 객체를 미리 알고있고, 이 객 체를 다른 객체로 바꿀 일도 없고, 널 값도 되지않는 다는 보장이 있을때는? -> 참조자 2. 그 이외에는 무조건 포인터
  • 11. 항목 2 : 가능한 C++ 스타일의 캐 스트를 즐겨 쓰자 1. go to 문과 함께 가장 기피해야할 키워드가 “캐스트” 2. C스타일의 캐스트는 어떤 타입을 다른 타입으로 아무 생 각 없이 바꾸어줌 -> 위험 3. C스타일의 캐스트를 써서 문제가 생길경우 프로그래머 입장에서 발견하기가 힘들다 4. C++스타일의 타입 캐스팅은 (C++ static_cast예시) (타입) 표현식 이 아니라 static_cast<타입>(표현식) 으로 쓴다. -> C++스타일의 캐스트가 더욱 잘 눈에 띈다.
  • 14. const_cast 1. 상수성이나 휘발성을 제거하는데 쓰이는 캐스팅
  • 15. const_cast는 언제 쓰이나? 1. const_cast를 써서 상수성을 제거 가능
  • 16. dynamic_cast 1. 상속 계층 관계를 가로지르거나 하향시킨 클래스타입 캐스팅 2. 기본클래스의 객체에 대한 포인터나 참조자의 타입을 파생 클래스, 혹은 형재 클래스의 타입으로 변환해 줌 3. 캐스팅 실패시 NULL값 리턴
  • 17. dynamic_cast는 언제 쓰이나 ? 1. Animal 포인터를 Cat포인터 타입으로 다운캐스팅 해준 다
  • 18. 다운 캐스팅의 제약 조건 1. 상속 계층 구조를 오갈 때에만 사용해야 함 2. 가상 함수가 없는 타입에는 적용할 수 없 음 3. 상수성 제거에 쓸 수 없음
  • 19. reinterpret_cast 1. 가장 흔한 용도는 함수 포인터 타입을 서로 바꾸는 것 2. 이 연산자가 적용된 후의 변환 결과는 거의 항상 컴파일 러에 따라 다르게 정의
  • 20. 주의점 1. 함수 포인터의 캐스팅은 소스의 이식성 을 떨어뜨림 2. 이런 캐스팅은 잘못된 결과를 낼 수도 있 음
  • 21. 항목2 정리 1. C++스타일이 C스타일의 캐스트보다 더 보기에 좋고, 읽어내기에도 쉽다 2. 다른 프로그래머에게 확실한 의미와 인 식성을 선사할 수 있음 3. 아무리 C++스타일의 캐스트라고 해도 최대한 피해야 하는 것이 권장사항
  • 22. 항목 3 : 배열과 다형성은 같은 수 준으로 놓고 볼 것이 아니다 1. 상속성이 주는 가장 중요한 혜택 중 하나는, 기본 클 래스 객체의 포인터나 참조자를 통해 파생 클래스 객체를 조작할 수 있다는 점 2. 이렇게 쓰이는 포인터나 참조자를 가리켜 “ 다형성 을 가지고 있다”라고 말함 3. 파생 클래스 객체의 배열을 기본 클래스 포인터나 참조자를 통해 조작하는 것도 됨
  • 23. 다형성과 포인터 산술 연산은 간단히 섞이지 않음 1. 배열이 삭제될 때, 배열의 각 요소 객체에 대해 소멸자가 호출 2. 기본 클래스 포인터를 통해 파생 클래스 객체의 배열을 삭제한 결과는 “정의되지 않음” 3. 어떤 구체 클래스부터 또 다른 구체 클래스를 파생시키는 일만 없으면, 객체의 배열을 다형적으로 조작하는 실수는 별로 하지 않는다
  • 24. 항목3 정리 1. 기본 클래스 포인터를 통해 파생 클래스 객체의 배열을 삭제한 결과는 “정의되지 않았다” 2. 다형성과 산술 연산은 간단히 섞이는 것 이 아님 3. 배열과 다형성은 물과 기름의 관계
  • 25. 항목 4 : 쓸데 없는 기본 생성자는 그냥 두지 말자 1. 생성자는 객체를 초기화하는 역할 2. 조심해야할 점은 어떤 객체의 경우 외부 정보 없이 는 완전한 초기화를 수행할 수 없는 경우가 있음 -> 클래스 설계에 따라 사원클래스에 ‘사원번호’가 없다 든지 이런 정보들이 없으면 초기화할 수 없음
  • 26. 기본 생성자가 없을때 문제점 1 1. 기본 생성자가 없으면 배열을 생성할 때 , 배열의 요소 로 들어가는 객체에 대해 생성자 매개변수를 지정할 수 없기때문에 배열 생성 불가능
  • 27. 생성자 매개변수를 입력하여 해 결 1. 생성자 매개변수를 직접 입력
  • 28. 포인터 배열을 이용하여 해결 1. 포인터의 배열을 만들어 각각이 하나의 객체를 가리키 도록 만들어줌
  • 29. 포인터 배열 사용의 문제점 1. 배열 내의 모든 포인터가 가리키는 객체를 삭제해야 함 -> 그렇지 않으면 메모리 누수 2. 필요한 메모리 사용량이 늘어남 -> 객체를 담을 메모리 공간 이외에 포인터를 담을 공간 또한 필요
  • 30. 기본 생성자가 없을때 문제점 21. 템플릿 기반의 컨테이너 클래스와 연계할 수 없다 2. 컨테이너 클래스를 인스턴스화하기 위해서는 템플릿 매개변 수로 들어가는 타입이 기본 생성자를 가지고 있어야 하기 때 문. 3. -> 기본 생성자가 없는 클래스를 템플릿 매개변수로 쓸 수 없 음!
  • 31. 항목 4 정리 1. 쓸 데 없는 기본 생성자는 클래스의 효율에 걸림돌 -> 멤버 함수들은 클래스의 멤버데이터가 제대로 초기화 되었는지를 검사해야하기 때문에 실행속도 느려짐 2. 추가된 검사 코드의 크기만큼 실행 파일이 커짐 3. 이를 막기위해 생성자가 객체의 멤버 데이터를 확실히 초기화 해야함 4. 특별한 상황이 아니면 기본생성자를 피해야 함
  • 32. 항목 5 : 사용자 정의 타입변환 함 수에 대한 주의를 놓지 말자 1. 암시적 타입변환을 수행하기 위해, 컴파일러가 사용 하는 함수를 제공할 것인가 말 것인가의 여부를 결 정할 수 있다 2. 컴파일러가 사용할 수 있는 타입변환 함수는 단일 인자 생성자와 암시적 타입변환 연산자이다 3. 단일 인자 생성자는 인자를 하나만 받아서 호출되는 생성자 4. 암시적 타입 연사자는 일종의 멤버 함수
  • 33. explicit키워드를 활용하자 1. 암시적 타입변환의 문제를 막 기위해 만들어 진것 2. 사용법도 상당히 단순 3. 앞에 키워드를 붙여주면 된다 4. 매개변수와 호출이 명확할 때 에만 이 생성자를 호출
  • 34. 항목 5 정리 1. explicit를 사용하여 암시적 타입변환을 막을 수 있음 2. explicit를 지원하지 않는 컴파일러라면 단일 인자 생 성자를 사용하지 않는 다른 방법을 사용해야 함 3. 컴파이러가 암시적 타입변환을 하도록 내버려두면 득보다 실이 많음
  • 35. 항목 6 : 증가 및 감소 연산자의 전위/후위 형태를 반드시 구분하 자 1. 증감 연산자의 전위 형태와 후위 형태는 서로 다른 타입을 반환 2. 전위 형태는 참조자 타입을 반환하고, 후위 형태는 const 객체 타입을 반환 3. 전위 연산자는 값을 변경시키고 값을 사용 4. 후위 연산자는 값을 사용하고 값을 변경
  • 36. 전위, 후위 연산의 차이 1. C++ 스펙에 전위/ 후위 연산자의 구현을 보면 전위는 값 을 변한 뒤 값을 사용하고, 후위는 값을 사용하고 값을 변경
  • 37. 후위 연산은 왜 Const가 아닌 객 체를 반환하는 것을 꺼려할까? 1. 기본 제공 타입에 대한 증가연산자의 동작과 맞지 않음 int 를 예로 들면 int i =1; i++++;로 쓰지 않는다(에러) 2. 사용자는 절대로 이런 괴상한 동작을 웃고 넘기지 않는다 -> 프로그래머 입장에서 직관적이지 않고 애매하다
  • 38. 후위연산과 전위연산의 효율 1. 후위 연산은 반환값으로 쓰기 위한 임시객체를 만들 고, 지역 변수로서 생겼다가 없어지는 임시 객체를 만듦 2. 전위연산자는 이런 임시 객체를 사용하지 않음 ->후위 연산보다 전위연산이 더 효율적 3. 두 연산자는 반환타입을 제외하면 하는 일이 같음
  • 39. 항목 6 정리 1. 함사용자 정의 타입을 가지고 작업할 때에는 되도록 전위 연산자를 사용할 것 2. 전위, 후위 연산자에 따라서 반환타입이 어떻게 되 는지 알아야 함
  • 40. 항목 7 : && , || 혹은 , 연산자는 오버로딩 대상이 절대로 아니다 1. C와 C++은 복합적인 불린 표현식을 평가할 때 단축 평가 처리를 할 수 있음, 표현식의 일부가 참 혹은 거 짓이란 것이 판명되면, 그 이후의 표현식은 스킵 char * p; if( (p != 0) && (strlen(p) >10 ) … ) 에서 p가 널 포인터이면 strlen은 호출하지 않고 종 료 _________________________________________ _ if( (index < lowerBound) || (index > upperBound )) 에서 index < lowerBound dㅣ면 뒤에 조건식은 스킵
  • 41. && 연산자 1. &&을 사용자가 임의로 변경 가능 2. &&을 변경한다는 것은 컴파일러가 다음과 같이 해석하게 한다는 것 3. 함수 호출이 이루어 질 때 모든 매개변수를 평가 4. 평가 순서를 명확하게 알지 못해 어떤 것을 먼저 처리할 것인지 알 수 없음 (단축평가는 왼쪽에서 오른쪽으로 표현식 평가) || 연산자도 마찬가지이다! &&, ||를 오버로딩 한다는 것은 단축평가에 문제가 생길 수 있음!
  • 42. , 연산자 1. 쉼표 연산자는 쉼표의 왼쪽에 있는 표현식을 먼저 평가 하고, 그 다음에 오른쪽에 있는 표현식을 평가하면서 진 행 도 오버로딩이 가능 하다, 하지만 오버리등을 하면 원래의 동작과
  • 43. 항목 7 정리 1. && 와 || 그리고 , 연산자는 함부로 오버로딩 하면 안 된다 -> 단축평가 순서 및 동작방식에 문제가 발생할 수 있음 2. 오버로딩이 가능한 연산자라도 연산자 오버로딩의 목적을 이해하고 써야 함
  • 44. 항목 8 : new 와 delete의 의미를 정확히 구분하고 이해하자 1. string *ps = new string(“memory Management”); new연산자의 동작은 2단계 요청한 타입의 객체를 담을 수 있는 크기의 메모리 할 당 할당된 메모리에 객체 초기화를 수행 2. operator new 함수는 void * operator new(size_t size); 이 함수의 반환 타입은 void*이다.
  • 45. new 연산자가 하는 일 1. new연자에서 생성자 호출 단계는 프로그래머가 손댈 수 없음, 컴파일러만이 가능
  • 46. 메모리 지정 new 1. 할당받은 미초기화 메모리가 있고, 객체 형태로 만들고 싶을 때 쓰는 방법 객체를 buffer로 지정되는 메모리에 생성한 후에 그 포인터를 반환
  • 47. 객체 삭체와 메모리 해제 1. 메모리 누수를 막기 위해, 할당한 메모리는 반드시 해제 2. 기본적으로 delete 연산자를 사용 3. operator delete 함수 이용
  • 48. 객체의 배열 메모리 해제 1. 단일 객체 해제와 달리 객체 배열의 해제는 operator new[]를 호출
  • 49. 항목 8 정리 1. new와 delete 연산자는 C++에서 기본적으로 제공되 는 함수 2. 이 연산자가 내부적으로 사용하는 메모리 할당 함수 및 해제 함수는 수정 가능 3. 하지만 이 연산자의 동작을 수정하는 것은 많은 위험 감수 -> 어차피 하는 일은 C++언어에서 고정되어 있 음