more effective c++ chap1~2

Post on 19-Jul-2015

122 Views

Category:

Education

9 Downloads

Preview:

Click to see full reader

TRANSCRIPT

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_cast1. 상속계층관계를가로지르거나하향시킨클래스타입캐스팅

2. 기본클래스의객체에대한포인터나참조자의타입을파생클래스,

혹은형재클래스의타입으로변환해줌3. 캐스팅실패시 NULL값리턴

dynamic_cast는언제쓰이나?

1. Animal 포인터를 Cat포인터타입으로다운캐스팅해준다

다운캐스팅의제약조건

1. 상속계층구조를오갈때에만사용해야함

2. 가상함수가없는타입에는적용할수없음

3. 상수성제거에쓸수없음

reinterpret_cast1. 가장흔한용도는함수포인터타입을서로바꾸는것

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++언어에서고정되어있음

top related