60
Effective C++ 1차 요약 과제

Effective c++ Chapter1,2

  • Upload
    -

  • View
    146

  • Download
    3

Embed Size (px)

Citation preview

Page 1: Effective c++ Chapter1,2

Effective C++

1차요약과제

Page 2: Effective c++ Chapter1,2

Chapter 1 C++에왔으면 C++의법을따르자

Page 3: Effective c++ Chapter1,2

기본용어정의

Declaration - 코드에사용되는 ‘어떤대상'의이름과타입을컴파일러에게알려주는것

Definition – 선언에서빠진구체적인세부사항을컴파일러에게제공하는것

Initialization – 어떤객체에최초의값을부여하는과정

Default constructor – 어떤인자도주어지지않은채로호출될수있는생성자

Page 4: Effective c++ Chapter1,2

Default constructor

Page 5: Effective c++ Chapter1,2

explicit

오류가발생할수있는암시적형식의변환을방지한다.

매개변수가하나뿐인 C++ ctors(생성자)는 암시적형식변환을자동을수행한다.

예를들어, ctor이문자열포인터매겨변수를예상할때, int를전달하는경우코드는 int를분자열포인터로변환하는코드를추가한다. 그러나이자동동작으로인해오류가발생할수있다.

암시적변환을방지하려면 explicit 키워드를 ctor 선언에추가할수있다. 이는강제로코드가올바를형식의매개변수를사용하거나올바른형식에대핸매개변수를캐스팅하게한다. 즉, 캐스팅을코드에서명시적으로표시하지못하면오류가발생한다.

Page 6: Effective c++ Chapter1,2

Copy constructor

어떤객체의초기화를위해그와같은타입의객체로부터초기화할때호출되는함수

Page 7: Effective c++ Chapter1,2

Copy assignment operator

같은타입의다른객체에어떤객체의값을복사하는용도로쓰이는함수

Page 8: Effective c++ Chapter1,2

Copy constructor & copy assignment

Page 9: Effective c++ Chapter1,2

STL(Standard Template Library)

C++ 표준라이브러리중하나

컨테이너(vector, list, set, map등), 반복자(vector<int>::iterator, set<string>::iterator 등), 알고리즘(for_each, find, sort 등) 및이들과관련된기능들이집결한결정체

컨테이너, 반복자, 알고리즘에관련된기능들의상당부분을함수객체(function object), 즉함수처럼동작하는 C++ 객체가차지하고있다.

Page 10: Effective c++ Chapter1,2

Undefined behavior

동작자체가글자그대로 ‘정의되어있지않다.’

실행시간에어떤현상이터질지확실히예측할수없다는뜻이다.

Page 11: Effective c++ Chapter1,2

Multiparadigm programming language

C

객체지향개념의 C++

템플릿 C++

STL

위 4가지 sublanguage들이 C++을구성한다.

Unified language, sublanguage federation

어떤경우에 C++의어떤부분을사용할지에대해서고민하라.

Page 12: Effective c++ Chapter1,2

#define을쓰려거든 const, enum, inline을…

#define 사용의문제점

#define ASPECT_RATIO 1.653

이경우, 우리에겐 ASPECT__RATIO가 symbolic name으로보이지만, 컴파일러에겐숫자상수로보인다.

컴파일에러가발생하면에러메시지에는 ASPECT_RATIO 대신에 1.653이나타난다.

ASPECT_RATIO를찾아가지않으면난감해질수있다.

#define ASPECT_RATIO 1.653 -> const double AspectRatio = 1.653;

Page 13: Effective c++ Chapter1,2

#define -> const 상수

#define 매크로를사용하면선행처리자에의해 ASPECT_RATIO가등장하기만하면 1.653으로모두바뀌면서목적코드안에 1.653의사본이등장횟수만큼들어가게된다.

상수타입의 AspectRatio는아무리여러번쓰이더라도사본은딱한개만생긴다.

결국, 상수가보동소수점실수타입일경우에는컴파일을거친최종코드의크기가 #define을썻을때보다작게나올수있다.

Page 14: Effective c++ Chapter1,2

#define -> const 상수주의할점

Constant pointer – 상수정의는대게헤더파일에넣는것이상례이므로 (다른소스파일이이것을include해서쓴다.) pointe는꼭 const로선언해주어야한다. Pointer가가리키는대상까지 const

로선언하는것이보통이다.

예) const char * const authorName = “Scott Meyers”;

char * 기반문자열보다는 string 객체가사용하기좋다.

예) const std::string authorName(“Scott Meyers”);

Page 15: Effective c++ Chapter1,2

정적클래스상수의선언과정의

Page 16: Effective c++ Chapter1,2

enum hack

Page 17: Effective c++ Chapter1,2

매크로함수의단점

Page 18: Effective c++ Chapter1,2

매크로함수의단점

Page 19: Effective c++ Chapter1,2

매크로함수의문제점해결

Page 20: Effective c++ Chapter1,2

inline 함수

프로그램의코드들가운데컴파일된함수코드가삽입된다.

프로그램은해당코드를수행하기위해일반함수수행처럼메모리에있는함수의주소를찾아점프할필요가없다.

일반함수보다약간이나마빠른수행속드를갖는다.

크기가큰함수를인라인함수로사용하면(10번 호출한다면프로그램코드사이에 10개의복사본이삽입된다.) 메모리낭비를유발할수도있다.

Page 21: Effective c++ Chapter1,2

항목 3: 낌새만보이면 const

const 키워드가붙은객체는외부변경을불가능하게한다는 ‘의미적인제약‘을소스코드수준에서붙인다.

컴파일러가이제약을단단히지켜준다.

어떤값이불변이어야한다는제작자의의도를컴파일러및다른프로그래머와나눌수있는수단

Page 22: Effective c++ Chapter1,2

const 사용

클래스바깥에서는전역혹은네임스페이이스유효범위의상수를선언하는데사용할수있다.

그리고파일, 함수 , 블록유효범위에서 static으로선언한객체에도 const를붙일수있다.

클래스내부의경우에는, 정적멤버및비정적데이터멤버모두를상수로선언할수있다.

그리고포인터의경우, 기본적으로포인터자체를상수로, 혹은포인터가가리키는데이터를상수로지정할수있다. 둘다지정할수도있고아무것도지정하지않을수도있다.

Page 23: Effective c++ Chapter1,2

const 사용

Page 24: Effective c++ Chapter1,2

STL iterator에서 const 사용

Page 25: Effective c++ Chapter1,2

상수멤버함수

멤버함수에붙은 const 키워드의역할은 “해당멤버함수가상수객체에대해호출될함수이다.”라는사실을알려주는것이다.

클래스의인터페이스를이해하기좋게하기위해서, 그클래스로만들어진객체를변경할수있는함수는무엇이고, 또변경할수없는함수는무엇인가를사용자쪽에서할수있도록한다.

이키워드를통해상수객체를사용할수있도록한다. C++ 프로그램의실행성능을높이는핵심기법중하나가객체전달을 ‘상수객체에대한참조자(reference-to-const)’로 진행하는것이다.

Page 26: Effective c++ Chapter1,2

const를활용한오버로딩

Page 27: Effective c++ Chapter1,2

비트수준상수성

어떤멤버함수가그객체의어떤데이터멤버도건드리지않아야그멤버함수가 ‘const’

즉, 그객체를구성하는비트들중어떤것도바꾸면안된다.

어떤포인터가가리키는대상을수정하는멤버함수들중비트수준상수성검사를통과하는멤버함수들이적지않다.

Page 28: Effective c++ Chapter1,2

비트수준상수성의문제점

Page 29: Effective c++ Chapter1,2

상수멤버함수와 mutable

Page 30: Effective c++ Chapter1,2

상수멤버및비상수멤버함수에서중복회피

Page 31: Effective c++ Chapter1,2

항목 4: 객체를사용하기전에반드시초기화

Page 32: Effective c++ Chapter1,2

initialization? assignment!

Page 33: Effective c++ Chapter1,2

초기화리스트를사용한 initialization

theName, theAddress, thePhones이 복사생성자에의해초기화

기본생성자호출후에복사대입연산자를연달아호출하는방법보다복사생성자를한번호출하는쪽이더효율적이다.

Page 34: Effective c++ Chapter1,2

매개변수없는생성자초기화

Page 35: Effective c++ Chapter1,2

클래스데이터멤버는모두초기화리스트에

기본제공타입의객체는사실초기화와대입에걸리는비용의차이가없다.

초기화리스트에서어떤멤버를빼먹었을때어떤멤버가초기화되지않을수있다는부담을해결할수있다.

기본제공타입의객체는초기화될지안될지장담할수없다.(undefined behavior)

상수이거나참조자로되어있는데이터멤버의경우엔반드시초기화되어야한다.(상수와 참조자는대입자체가불가능하기때문이다.)

Page 36: Effective c++ Chapter1,2

객체를구성하는데이터의초기화순서

기본클래스는파생클래스보다먼저초기화된다.

클래스데이터멤버는그들이선언된순서대로초기화된다.

Page 37: Effective c++ Chapter1,2

static object

자신이생성된시점부터프로그램이끝날때까지살아있는객체를일컫는다.

스택객체및힙기반객체는정적객체가될수없다.

전역객체(non-local static object)

네임스페이스유효범위에서정의된객체(non-local static object)

클래스안에서 static으로선언된객체(non-local static object)

함수안에서 static으로선언된객체(local static object)

파일유효범위에서 static으로정의된객체(non-local static object)

static object는 main() 함수의실행이끝날때소멸자가호출된다.

Page 38: Effective c++ Chapter1,2

translation unit

컴파일을통해하나의목적파일(object file)을만드는바탕이되는소스코드

기본적으로는소스파일하나가되는데, 그파일이 #include 하는파일들까지합쳐서하나의번역단위가된다.

Page 39: Effective c++ Chapter1,2

translation unit과 non-local static object

서로다른 translation unit에정의된 non-local static object 사이상대적인초기화순서는정해져있지않다.

설계에변화를주어이문제를해결하여야한다.

Page 40: Effective c++ Chapter1,2

발생할수있는문제예시

Page 41: Effective c++ Chapter1,2

문제해결방법

비지역정적객체를하나씩맡는함수를준비한다.

이안에각객체를넣는다.

함수속에서도이들은정적객체로선언한다.

그함수에서는이들에대한참조자를반환하게한다.

사용자쪽에서는비지역정적객체를직접참조하는과거의폐단을버리고함수호출로대신한다.

결과적으로 ‘비지역정적객체’가 ‘지역정적객체’로바뀐것이다.

Singleton pattern의전형적인구현양식

객체들의초기화순서를제대로맞춰둔다는전제조건이뒷받침되어야한다.

객체 B가초기화되기전에객체 A가초기화되어야하는데, A의초기화가 B의초기화에의존하도록만들어져있다면문제는해결되지않는다.

다중스레드에서는몰라도단일스레드애플리케이션에서는확실하다.

Page 42: Effective c++ Chapter1,2

문제해결예시

Page 43: Effective c++ Chapter1,2

Chapter 2 생성자, 소멸자및대입연산자

Page 44: Effective c++ Chapter1,2

생성자, 소멸자, 대입연산자

생성자 : 새로운객체를메모리에만드는데필요한과정을제어하고객체의초기화를맡는함수

소멸자 : 객체를없앰과동시에그객체가메모리에서적절히사라질수있도록하는과정을제어하는함수

대입연산자 : 기존의객체에다른객체의값을줄때사용하는함수

Page 45: Effective c++ Chapter1,2

항목 5: C++가은근슬쩍만들어호출해……

클래스안에직접선언해넣지않으면컴파일러가저절로선언해주도록되어있는멤버함수가있다.

copy constructor, copy assignment, destructor

이런경우컴파일러는 public 멤버이며 inline함수의형태로저절로선언하게된다.

Page 46: Effective c++ Chapter1,2

저절로만들어지는조건

Page 47: Effective c++ Chapter1,2

복사생성자를생성하는경우

Page 48: Effective c++ Chapter1,2

복사대입연산자를생성하는경우

Page 49: Effective c++ Chapter1,2

컴파일러가생성한함수가필요없으면생성을막자

복사생성자와복사대입연산자가저절로만들어지는것을막지않으면의도치않은문제가발생할수있다.

복사생성자와복사대입연산자를 public 멤버가아닌 private 멤버로선언하자.

명시적으로선언되기때문에컴파일러는자신의기본버전을만들수없게된다.

Page 50: Effective c++ Chapter1,2

private 멤버함수만으로충분한가?

private 함수는그클래스의멤버함수및 friend 함수가호출할수있다.

호출될경우를대비하여복사생성자와복사대입연산자를 define하지않으면된다.

private 멤버로선언 + define(구현)하지 않기로앞의문제를해결할수있다.

Page 51: Effective c++ Chapter1,2

private 멤버함수 + 구현안하기

Page 52: Effective c++ Chapter1,2

‘private 멤버함수 + 선언만’ 담당하는클래스

Page 53: Effective c++ Chapter1,2

factory function

factory function : 새로생성된파생클래스객체에대한기본클래스포인터를반환하는함수

Page 54: Effective c++ Chapter1,2

factory function 해제시주의할점

getTimeKeeper 함수가반환하는포인터느파생클래스객체에대한포인터이다.

이포인터가가리키는객체가삭제될때는기본클래스포인터를통해삭제된다.

기본클래스에들어있는소멸자가 non-

virtual destructor이다.

C++의규정에의하면, 기본클래스포인터를통해파생클래스객체가삭제될때그기본클래스에비가상소멸자가들어있으면프로그램동작은 undefined behavior

Page 55: Effective c++ Chapter1,2

가상소멸자로 factory function 문제해결

virtual ~ TimeKeeper(); 하나로해결가능

기본클래스에는대개소멸자외에도가상멤버함수들이들어있는경우가있는데, 이는파생클래스를구현할때해당함수를역할에따라맞추는작업을허용한다는의미이다.

가상함수를하나라도가진클래스는가상소멸자를가져야하는게대부분맞다.

가상소멸자를갖고있지않은클래스는기본클래스로쓰일의지를상실한것이다.

반대로기본클래스로의도하지않은클래스에대해소멸자를가상으로선언하는것또한좋지않다.

정리하면, 클래스에가상함수가하나라도들어있는경우에만가상소멸자를선언한다.

Page 56: Effective c++ Chapter1,2

가상소멸자가없는클래스로부터파생문제

Page 57: Effective c++ Chapter1,2

소멸자를통한예외처리

Page 58: Effective c++ Chapter1,2

소멸자에서발생하는예외처리1

Page 59: Effective c++ Chapter1,2

소멸자에서발생하는예외처리2

Page 60: Effective c++ Chapter1,2

대입연산자는 *this의참조자를반환