SlideShare a Scribd company logo
effective c++ 구현, 상속, 객체지향 설계
구현
특정 함수 내에서 변수가 선언된 후 예외 때문에 반환되어 버린다면 자원 낭비다.
또, 생성 시 초기화(복사 생성자)를 하지 않으면
생성과 대입이 두 번에 걸쳐 일어나게 되므로 이 또한 낭비다.
So, 될 수 있으면 자원은 사용하기 직전에 초기화 하자.
루프에 사용할 변수를 만드는 경우,
루프 밖에서 정의하고, 안에서 대입하는 경우(A)와
루프 안에서 복사 생성자로 정의하는 경우(B),
두 가지로 나누어 볼 수 있다.
A : 생성자 1번 + 소멸자 1번 + 대입 n번
B : 생성자 n번 + 소멸자 n번
대입이 생성자+소멸자 보다 저렴할 때, A방법을 쓰자. (반대라면 B)
But, A방법은 유효범위가 넓어지므로 프로그램 이해도 및 유지보수에 안 좋을 수 있다.
변수 정의는 늦출 수 있는 데까지 늦추자
구형 캐스트 : int(varname) , (int)varname
C++ 신형 캐스트
const_cast<> : 변수에 붙어있는 const를 뗄 때 사용
dynamic_cast<>
: 안전한 다운캐스팅을 위해 해당 객체가 특정 상속계통에 속한 것인지 아닌지를 판단
이상한 게 if문 안에 대입연산자로 넣어주면서 판단을 함.
Window window;
if ( SpecialWindow *psw = dynamic_cast<SpecialWindow*>(window))
** 성능이 안 좋다. 특히 폭포식은 위험함
reinterpret_cast<> : 하부 수준 캐스팅(bit수준), 구현환경에 의존적, 잘안씀
static_cast<> : 이외 다른 캐스트들(흔히 씀)
** doSomeWork(Widget(15)); 같은 방식은 객체를 만드는 게 아니라 int형을 캐스팅하는거
구형 캐스트 보다는 C++ 스타일 캐스트를 쓰자.
But, 될 수 있으면 캐스팅이 없는 것이 좋은 설계다!!
캐스팅은 절약, 또 절약
핸들 : 다른 객체에 손댈 수 있게 하는 매개자(참조자, 포인터, 반복자 등도 큰 의미에서 핸들)
Point& upperLeft() const { return pData->ulhc; }
라는 함수가 있다할 때, 얼핏 보면 const라 ulhc를 바꿀 수 없을 것 같아 보인다.
하지만 이건 pData->ulhc 그 자체를 다른 객체로 대체할 수 없을 뿐(대입 연산이 안됨)
ulhc객체 내부의 set함수 등을 이용하여 객체를 바꾸는 것은 가능하다. 따라서
const Point& upperLeft() const { return pData->ulhc; }
식으로 머리에 const를 붙이면 반환 값이 상수가 되서 객체 자체를 상수화 한다.
문제는 해결되는 듯 하지만, 핸들은 결국 캡슐화를 해치고 dangling pointer를 만들 가능성이
있다.
내부에서 사용하는 객체에 대한 ‘핸들’을 반환하는 코드는 피하
자
예외 안전성을 가진 함수는..
자원이 새지 않는다.(중간에 예외발생으로 종료되어도 메모리릭 없이)
자료구조가 더럽혀지지 않는다.(변수 및 포인터들이 가리키는 값들이 정상적이어야..)
세 가지 중 하나의 방식으로 보장한다.
기본적인 보장 : 위의 두 가지를 만족, But 결과를 사용자가 예측할 수 없음
강력한 보장 : 원자적으로 동작, 호출이 성공하면 완벽한 성공, 실패하면 호출이 없었던 것처
럼!!
예외불가 보장 : 예외를 절대로 던지지 않겠다. 기본제공 타입 등이 보장되나 대부분은 어렵다.
결국 강력한 보장이 되도록 만드는 게 좋다. 어떻게?
스마트 포인터를 적극 활용하자.
reset()등의 함수는 확실히 new가 될 때만 가지고 있는 자원을 delete한다.
mutex등도 자원관리 담당 객체를 활용하자.
Copy-and-swap 방식을 활용하자!
pimpl 관용구를 활용하자(25번 항목의 swap도 참고)
예외 안전성을 확보하자
Inline함수는 호출문을 함수 본체로 바꿔치기 한다.
함수호출 시 오버헤드가 없다. 컴파일러가 문맥별 최적화를 해줄 수 있다.
But 메모리가 부족한 환경에서 쓰면 성능이 떨어진다.
컴파일러 선에서 무시할 수 있다.
So, 작은 함수에 사용하자.(함수 호출 오버헤드만큼 작은..)
암시적인 방법 : 선언부에서 정의까지, int age() const { return value; }
명시적인 방법 : 정의 앞에 inline 키워드 붙이기.
가상함수 호출은 안됨 : inline은 컴파일러가 하는 데, 가상함수 호출은 runtime에 하니까
생성자, 소멸자에는 쓰지 말 것 : 컴파일러가 변수나 부모 클래스의 생성자도 실행하는 부분을
슬쩍 끼워넣을텐데 그 모든 것이 inline으로 만들어져야 함
Inline함수는 이해하고 사용하자
정의부에 대한 의존성을 선언부에 대한 의존성으로
포인터, 참조자에 대해서는 클래스 전방 선언으로 의존도를 줄일 수 있다. (실제 객체의 경우
컴파일 할 때 컴파일러가 그 크기를 알아야 하는데 껍데기만 있는 전방선언 클래스로는 알 수
없음.)
핸들 클래스 이용(pimpl관용구 사용)
person이라는 선언부를 위한 클래스와 personImpl이라는 정의부를 위한 클래스 두 개로 쪼갬
선언부 클래스와 구현부 클래스는 함수가 동일,
선언부 멤버 변수로 구현부 클래스를 포인터로 가짐, 구현부는 실제 값들을 가짐.
선언부 함수들의 구현은 구현부 함수들을 호출하는 걸로. 생성자에서는 pimpl포인터 초기화
사용자는 person만 include하면 됨, 이때 person이 바로 핸들 클래스
인터페이스 클래스 (팩토리 함수 이용)
person이라는 인터페이스 클래스와 이를 상속받은 realPerson 두 클래스로 구현
person에서는 필요한 함수들을 순수 가상 함수로 선언, 팩토리 함수인 create을 구현
static create()함수는 person 포인터형에 realPerson을 담아서 제공.
파일 사이의 컴파일 의존성을 최대로 줄이자!!
상속, 그리고 객체 지향 설계
public 상속은 is-a 관계다.
즉, 자식 클래스는 부모가 될 수 있어도
부모 클래스는 자식이 될 수 없다.
** private은 다르다!!
public 상속 모형은 반드시 is-a를 따르도록 하자
부모와 자식 클래스에 동일한 이름의 함수가 있을 때,
자식 클래스의 객체는 해당 함수를 호출하기 위해
먼저 가까운 유효범위(자식 클래스)를 뒤지고 부모 클래스로 간다.
즉, 부모 클래스의 함수는 가려진다.
문제는 부모 클래스에 있는 동일 이름의 오버로딩된 다른 함수도 가려진다는 것.
이 때, using Base::mf1; 등으로 가려진 함수를 꺼내 쓸 수 있다.
전달 함수로 꺼낼 수도 있음
상속된 이름을 숨기는 일은 피하자
순수 가상 함수를 선언하는 것은 인터페이스만 물려주려는 것
가상 함수를 선언하는 것은 인터페이스와 그 함수의 기본 구현 형태를 물려주려는 것.
: 상속받은 함수만의 구현 형태가 없다면 기본 구현 형태를 써도 좋다.
** 순수 가상함수의 정의부분을 만들어 두고 자식 클래스에서 사용하는 방법도 있다.
비가상 함수를 선언하는 것은 인터페이스와 구현을 둘 다 물려주려는 것.
: 이 함수는 재정의 하지 마라. 이 형태로 써라!!
상속 시 주의할 점
상속관계가 생긴다면 기본 클래스에는 최소한 가상 함수가 하나는 있을 것이다.(소멸자라도..)
모든 함수를 가상 함수로 만드는 것도 좋지 않다.(자신감이 없나? 하는 느낌을 줄 수도!!)
인터페이스 상속과 구현 상속의 차이를 제대로 구별하자
NVI (비가상 함수 인터페이스)
public : healthValue()는 private : virtual doHealthValue()를 호출한다.
여기서 healthValue가 인터페이스로 사용되며 wrapper라 부른다.
wrapper를 통해서 doHealthValue()가 언제 실행될 지를 정하고
각 파생클래스에서는 doHealthValue()의 정의를 구현한다.
** 여기서 doHealthValue는 protected일 수도 있다.(파생클래스에서 기본 구현함수를 쓸 때)
함수 포인터로 구현한 전략
외부에 함수를 만들고 클래스 내부에서 함수 포인터를 이용 클래스 객체 자신을 매개변수로 하
여 기능을 수행하는 방법. 함수 포인터에 대한 개념공부가 더 필요할 듯
tr1::function 도 함수포인터를 제공해준다.
전략 패턴 사용
특정 기능 수행만 전담으로 하는 클래스를 외부에 만들고 원래 클래스가 그 클래스에 대한 객
체를 가리키는 포인터를 들고 있게 하는 방법, 포인터는 생성자에서 초기화.
가상 함수대신 쓸 것도 생각해보자
비가상 함수를 파생클래스에서 재정의하면 부모 클래스형 포인터에서 자식 클래스 객체를 가
리킬 경우 부모 클래스의 비가상함수가 호출된다. virtual이 아니니깐
상속받은 비가상 함수는 절대 재정의 하지 말자
상속받은 비가상 함수를 파생클래스에서 재정의하는 것은 금물
상속받은 함수를 재정의 한다는 건 일단 가상 함수만 가능하다.
문제는 기본 매개변수 값은 정적으로 바인딩되고 가상 함수는 동적으로 바인딩 된다는 것.
따라서 부모 클래스 형 포인터로 자식 클래스 객체를 가리킬 때,
부모 클래스의 매개변수를 이용해서 자식 클래스의 함수를 호출하게 된다.
상속받은 함수의 기본 매개변수 값은 절대로 재정의 하지 말자
어떤 클래스가 다른 클래스의 객체를 멤버 변수로 가지고 있을 때, 이를 객체 합성이라 한다.
객체 합성은 두 가지 측면에서 접근할 수 있는데,
현실에 있는 사물을 본 뜬 응용영역에서는 has-a 측면으로 접근하고
시스템 구현을 위한 구현영역에서는 is-implemented-interm-of 측면에서 접근하자.
std::list로 set을 구현할 때, 이를 상속받는 것이 아니라 객체 합성하여 내부적으로 접근해야..
has-a 혹은 is-implemented-interm-of 를 모형화할 때는 객체 합성을 사용하자
private 상속은 is-implemented-in-terms-of 를 의미한다.
객체 합성과 달리 private상속은 공백 기본 클래스 최적화를 활성화 할 수 있다.
private상속은 심사숙고해서 구현하자
다중 상속은 모호성 문제를 일으킬 수 있다. 따라서 가상 상속을 활용하면 좋다.
연산 복잡도를 줄이기 위해 가상 상속 기본 클래스에는 데이터를 두지 말자.
하나는 인터페이스를 하나는 구현을 돕는 private 상속을 이용하는 것이 적법하다.
다중 상속은 심사숙고해서 구현하자

More Related Content

What's hot

More effective c++ 항목30부터
More effective c++ 항목30부터More effective c++ 항목30부터
More effective c++ 항목30부터
Dong Chan Shin
 
More effective c++ chapter1,2
More effective c++ chapter1,2More effective c++ chapter1,2
More effective c++ chapter1,2문익 장
 
Effective c++ 1,2
Effective c++ 1,2Effective c++ 1,2
Effective c++ 1,2
세빈 정
 
Effective c++ 정리 1~2
Effective c++ 정리 1~2Effective c++ 정리 1~2
Effective c++ 정리 1~2
Injae Lee
 
Effective c++ Chapter1,2
Effective c++ Chapter1,2Effective c++ Chapter1,2
Effective c++ Chapter1,2문익 장
 
Effective C++ Chaper 1
Effective C++ Chaper 1Effective C++ Chaper 1
Effective C++ Chaper 1
연우 김
 
Effective c++ chapter 1,2 요약
Effective c++ chapter 1,2 요약Effective c++ chapter 1,2 요약
Effective c++ chapter 1,2 요약
Nam Hyeonuk
 
Effective c++ 2
Effective c++ 2Effective c++ 2
Effective c++ 2현찬 양
 
More effective c++ 1
More effective c++ 1More effective c++ 1
More effective c++ 1현찬 양
 
More effective c++ 3
More effective c++ 3More effective c++ 3
More effective c++ 3현찬 양
 
Effective c++ 1
Effective c++ 1Effective c++ 1
Effective c++ 1현찬 양
 
Effective c++chapter3
Effective c++chapter3Effective c++chapter3
Effective c++chapter3
성연 김
 
Ec++ 3,4 summary
Ec++ 3,4 summaryEc++ 3,4 summary
Ec++ 3,4 summarySehyeon Nam
 
M1 2 1
M1 2 1M1 2 1
M1 2 1nexthw
 
[Swift] Generics
[Swift] Generics[Swift] Generics
[Swift] Generics
Bill Kim
 
Effective c++chapter4
Effective c++chapter4Effective c++chapter4
Effective c++chapter4
성연 김
 
외계어 스터디 3/5 function and object
외계어 스터디 3/5   function and object외계어 스터디 3/5   function and object
외계어 스터디 3/5 function and object
민태 김
 
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
 
모어 이펙티브 c++ 1,2장 스터디
모어 이펙티브 c++ 1,2장 스터디모어 이펙티브 c++ 1,2장 스터디
모어 이펙티브 c++ 1,2장 스터디
quxn6
 

What's hot (20)

More effective c++ 항목30부터
More effective c++ 항목30부터More effective c++ 항목30부터
More effective c++ 항목30부터
 
5 6 1
5 6 15 6 1
5 6 1
 
More effective c++ chapter1,2
More effective c++ chapter1,2More effective c++ chapter1,2
More effective c++ chapter1,2
 
Effective c++ 1,2
Effective c++ 1,2Effective c++ 1,2
Effective c++ 1,2
 
Effective c++ 정리 1~2
Effective c++ 정리 1~2Effective c++ 정리 1~2
Effective c++ 정리 1~2
 
Effective c++ Chapter1,2
Effective c++ Chapter1,2Effective c++ Chapter1,2
Effective c++ Chapter1,2
 
Effective C++ Chaper 1
Effective C++ Chaper 1Effective C++ Chaper 1
Effective C++ Chaper 1
 
Effective c++ chapter 1,2 요약
Effective c++ chapter 1,2 요약Effective c++ chapter 1,2 요약
Effective c++ chapter 1,2 요약
 
Effective c++ 2
Effective c++ 2Effective c++ 2
Effective c++ 2
 
More effective c++ 1
More effective c++ 1More effective c++ 1
More effective c++ 1
 
More effective c++ 3
More effective c++ 3More effective c++ 3
More effective c++ 3
 
Effective c++ 1
Effective c++ 1Effective c++ 1
Effective c++ 1
 
Effective c++chapter3
Effective c++chapter3Effective c++chapter3
Effective c++chapter3
 
Ec++ 3,4 summary
Ec++ 3,4 summaryEc++ 3,4 summary
Ec++ 3,4 summary
 
M1 2 1
M1 2 1M1 2 1
M1 2 1
 
[Swift] Generics
[Swift] Generics[Swift] Generics
[Swift] Generics
 
Effective c++chapter4
Effective c++chapter4Effective c++chapter4
Effective c++chapter4
 
외계어 스터디 3/5 function and object
외계어 스터디 3/5   function and object외계어 스터디 3/5   function and object
외계어 스터디 3/5 function and object
 
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++
 
모어 이펙티브 c++ 1,2장 스터디
모어 이펙티브 c++ 1,2장 스터디모어 이펙티브 c++ 1,2장 스터디
모어 이펙티브 c++ 1,2장 스터디
 

Similar to 이펙티브 C++ 5,6 장 스터디

Effective c++ 1~8장
Effective c++ 1~8장 Effective c++ 1~8장
Effective c++ 1~8장
Shin heemin
 
Effective c++chapter1 and2
Effective c++chapter1 and2Effective c++chapter1 and2
Effective c++chapter1 and2
성연 김
 
Chapter5 ~ 6
Chapter5 ~ 6Chapter5 ~ 6
Chapter5 ~ 6Injae Lee
 
모어 이펙티브 c++ 5장 스터디
모어 이펙티브 c++ 5장 스터디모어 이펙티브 c++ 5장 스터디
모어 이펙티브 c++ 5장 스터디
quxn6
 
Effective c++ 3
Effective c++ 3Effective c++ 3
Effective c++ 3현찬 양
 
Effective cpp
Effective cppEffective cpp
Effective cpp
TonyCms
 
모어이펙티브 C++ 3,4장 예외, 효율 스터디
모어이펙티브 C++ 3,4장 예외, 효율 스터디모어이펙티브 C++ 3,4장 예외, 효율 스터디
모어이펙티브 C++ 3,4장 예외, 효율 스터디
quxn6
 
[C언어]함수오버로딩과오버라이딩
[C언어]함수오버로딩과오버라이딩[C언어]함수오버로딩과오버라이딩
[C언어]함수오버로딩과오버라이딩
jusingame
 
Effective c++ chapter5 6_ 131039 신동찬
Effective c++ chapter5 6_ 131039 신동찬Effective c++ chapter5 6_ 131039 신동찬
Effective c++ chapter5 6_ 131039 신동찬Dong Chan Shin
 
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
 
Effective C++ Chapter 1 Summary
Effective C++ Chapter 1 SummaryEffective C++ Chapter 1 Summary
Effective C++ Chapter 1 Summary
SeungYeonChoi10
 
M5 1 1
M5 1 1M5 1 1
M5 1 1nexthw
 
More effective c++ chapter4 이후 항목 29까지
More effective c++ chapter4 이후 항목 29까지More effective c++ chapter4 이후 항목 29까지
More effective c++ chapter4 이후 항목 29까지
Dong Chan Shin
 
Effective c++(chapter 5,6)
Effective c++(chapter 5,6)Effective c++(chapter 5,6)
Effective c++(chapter 5,6)문익 장
 
Modern C++ 프로그래머를 위한 CPP11/14 핵심
Modern C++ 프로그래머를 위한 CPP11/14 핵심Modern C++ 프로그래머를 위한 CPP11/14 핵심
Modern C++ 프로그래머를 위한 CPP11/14 핵심흥배 최
 
More effective c++ chapter3 4
More effective c++ chapter3 4More effective c++ chapter3 4
More effective c++ chapter3 4Dong Chan Shin
 
객체지향 단어가 의미하는 것
객체지향 단어가 의미하는 것객체지향 단어가 의미하는 것
객체지향 단어가 의미하는 것
jaypi Ko
 

Similar to 이펙티브 C++ 5,6 장 스터디 (20)

Effective c++ 1~8장
Effective c++ 1~8장 Effective c++ 1~8장
Effective c++ 1~8장
 
Effective c++chapter1 and2
Effective c++chapter1 and2Effective c++chapter1 and2
Effective c++chapter1 and2
 
Chapter5 ~ 6
Chapter5 ~ 6Chapter5 ~ 6
Chapter5 ~ 6
 
MEC++ 5
MEC++ 5MEC++ 5
MEC++ 5
 
모어 이펙티브 c++ 5장 스터디
모어 이펙티브 c++ 5장 스터디모어 이펙티브 c++ 5장 스터디
모어 이펙티브 c++ 5장 스터디
 
Effective c++ 3
Effective c++ 3Effective c++ 3
Effective c++ 3
 
Effective cpp
Effective cppEffective cpp
Effective cpp
 
모어이펙티브 C++ 3,4장 예외, 효율 스터디
모어이펙티브 C++ 3,4장 예외, 효율 스터디모어이펙티브 C++ 3,4장 예외, 효율 스터디
모어이펙티브 C++ 3,4장 예외, 효율 스터디
 
[C언어]함수오버로딩과오버라이딩
[C언어]함수오버로딩과오버라이딩[C언어]함수오버로딩과오버라이딩
[C언어]함수오버로딩과오버라이딩
 
Effective c++ chapter5 6_ 131039 신동찬
Effective c++ chapter5 6_ 131039 신동찬Effective c++ chapter5 6_ 131039 신동찬
Effective c++ chapter5 6_ 131039 신동찬
 
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
 
Effective C++ Chapter 1 Summary
Effective C++ Chapter 1 SummaryEffective C++ Chapter 1 Summary
Effective C++ Chapter 1 Summary
 
M5 1 1
M5 1 1M5 1 1
M5 1 1
 
More effective c++ chapter4 이후 항목 29까지
More effective c++ chapter4 이후 항목 29까지More effective c++ chapter4 이후 항목 29까지
More effective c++ chapter4 이후 항목 29까지
 
Effective c++(chapter 5,6)
Effective c++(chapter 5,6)Effective c++(chapter 5,6)
Effective c++(chapter 5,6)
 
Modern C++ 프로그래머를 위한 CPP11/14 핵심
Modern C++ 프로그래머를 위한 CPP11/14 핵심Modern C++ 프로그래머를 위한 CPP11/14 핵심
Modern C++ 프로그래머를 위한 CPP11/14 핵심
 
MEC++ 3,4
MEC++ 3,4MEC++ 3,4
MEC++ 3,4
 
More effective c++ chapter3 4
More effective c++ chapter3 4More effective c++ chapter3 4
More effective c++ chapter3 4
 
객체지향 단어가 의미하는 것
객체지향 단어가 의미하는 것객체지향 단어가 의미하는 것
객체지향 단어가 의미하는 것
 

More from quxn6

모어이펙티브 C++ 5,6
모어이펙티브 C++ 5,6모어이펙티브 C++ 5,6
모어이펙티브 C++ 5,6
quxn6
 
C++11 Tuple
C++11 TupleC++11 Tuple
C++11 Tuplequxn6
 
이펙티브 C++ 789 공부
이펙티브 C++ 789 공부이펙티브 C++ 789 공부
이펙티브 C++ 789 공부
quxn6
 
비실사렌더링-툰 쉐이딩
비실사렌더링-툰 쉐이딩비실사렌더링-툰 쉐이딩
비실사렌더링-툰 쉐이딩
quxn6
 
중급 소켓프로그래밍
중급 소켓프로그래밍중급 소켓프로그래밍
중급 소켓프로그래밍quxn6
 
입체충돌처리
입체충돌처리입체충돌처리
입체충돌처리
quxn6
 
introduce unity3D and playmaker basic
introduce unity3D and playmaker basicintroduce unity3D and playmaker basic
introduce unity3D and playmaker basic
quxn6
 
TCP echo 서버 및 클라이언트 예제 스터디
TCP echo 서버 및 클라이언트 예제 스터디TCP echo 서버 및 클라이언트 예제 스터디
TCP echo 서버 및 클라이언트 예제 스터디quxn6
 

More from quxn6 (8)

모어이펙티브 C++ 5,6
모어이펙티브 C++ 5,6모어이펙티브 C++ 5,6
모어이펙티브 C++ 5,6
 
C++11 Tuple
C++11 TupleC++11 Tuple
C++11 Tuple
 
이펙티브 C++ 789 공부
이펙티브 C++ 789 공부이펙티브 C++ 789 공부
이펙티브 C++ 789 공부
 
비실사렌더링-툰 쉐이딩
비실사렌더링-툰 쉐이딩비실사렌더링-툰 쉐이딩
비실사렌더링-툰 쉐이딩
 
중급 소켓프로그래밍
중급 소켓프로그래밍중급 소켓프로그래밍
중급 소켓프로그래밍
 
입체충돌처리
입체충돌처리입체충돌처리
입체충돌처리
 
introduce unity3D and playmaker basic
introduce unity3D and playmaker basicintroduce unity3D and playmaker basic
introduce unity3D and playmaker basic
 
TCP echo 서버 및 클라이언트 예제 스터디
TCP echo 서버 및 클라이언트 예제 스터디TCP echo 서버 및 클라이언트 예제 스터디
TCP echo 서버 및 클라이언트 예제 스터디
 

이펙티브 C++ 5,6 장 스터디

  • 1. effective c++ 구현, 상속, 객체지향 설계
  • 3. 특정 함수 내에서 변수가 선언된 후 예외 때문에 반환되어 버린다면 자원 낭비다. 또, 생성 시 초기화(복사 생성자)를 하지 않으면 생성과 대입이 두 번에 걸쳐 일어나게 되므로 이 또한 낭비다. So, 될 수 있으면 자원은 사용하기 직전에 초기화 하자. 루프에 사용할 변수를 만드는 경우, 루프 밖에서 정의하고, 안에서 대입하는 경우(A)와 루프 안에서 복사 생성자로 정의하는 경우(B), 두 가지로 나누어 볼 수 있다. A : 생성자 1번 + 소멸자 1번 + 대입 n번 B : 생성자 n번 + 소멸자 n번 대입이 생성자+소멸자 보다 저렴할 때, A방법을 쓰자. (반대라면 B) But, A방법은 유효범위가 넓어지므로 프로그램 이해도 및 유지보수에 안 좋을 수 있다. 변수 정의는 늦출 수 있는 데까지 늦추자
  • 4. 구형 캐스트 : int(varname) , (int)varname C++ 신형 캐스트 const_cast<> : 변수에 붙어있는 const를 뗄 때 사용 dynamic_cast<> : 안전한 다운캐스팅을 위해 해당 객체가 특정 상속계통에 속한 것인지 아닌지를 판단 이상한 게 if문 안에 대입연산자로 넣어주면서 판단을 함. Window window; if ( SpecialWindow *psw = dynamic_cast<SpecialWindow*>(window)) ** 성능이 안 좋다. 특히 폭포식은 위험함 reinterpret_cast<> : 하부 수준 캐스팅(bit수준), 구현환경에 의존적, 잘안씀 static_cast<> : 이외 다른 캐스트들(흔히 씀) ** doSomeWork(Widget(15)); 같은 방식은 객체를 만드는 게 아니라 int형을 캐스팅하는거 구형 캐스트 보다는 C++ 스타일 캐스트를 쓰자. But, 될 수 있으면 캐스팅이 없는 것이 좋은 설계다!! 캐스팅은 절약, 또 절약
  • 5. 핸들 : 다른 객체에 손댈 수 있게 하는 매개자(참조자, 포인터, 반복자 등도 큰 의미에서 핸들) Point& upperLeft() const { return pData->ulhc; } 라는 함수가 있다할 때, 얼핏 보면 const라 ulhc를 바꿀 수 없을 것 같아 보인다. 하지만 이건 pData->ulhc 그 자체를 다른 객체로 대체할 수 없을 뿐(대입 연산이 안됨) ulhc객체 내부의 set함수 등을 이용하여 객체를 바꾸는 것은 가능하다. 따라서 const Point& upperLeft() const { return pData->ulhc; } 식으로 머리에 const를 붙이면 반환 값이 상수가 되서 객체 자체를 상수화 한다. 문제는 해결되는 듯 하지만, 핸들은 결국 캡슐화를 해치고 dangling pointer를 만들 가능성이 있다. 내부에서 사용하는 객체에 대한 ‘핸들’을 반환하는 코드는 피하 자
  • 6. 예외 안전성을 가진 함수는.. 자원이 새지 않는다.(중간에 예외발생으로 종료되어도 메모리릭 없이) 자료구조가 더럽혀지지 않는다.(변수 및 포인터들이 가리키는 값들이 정상적이어야..) 세 가지 중 하나의 방식으로 보장한다. 기본적인 보장 : 위의 두 가지를 만족, But 결과를 사용자가 예측할 수 없음 강력한 보장 : 원자적으로 동작, 호출이 성공하면 완벽한 성공, 실패하면 호출이 없었던 것처 럼!! 예외불가 보장 : 예외를 절대로 던지지 않겠다. 기본제공 타입 등이 보장되나 대부분은 어렵다. 결국 강력한 보장이 되도록 만드는 게 좋다. 어떻게? 스마트 포인터를 적극 활용하자. reset()등의 함수는 확실히 new가 될 때만 가지고 있는 자원을 delete한다. mutex등도 자원관리 담당 객체를 활용하자. Copy-and-swap 방식을 활용하자! pimpl 관용구를 활용하자(25번 항목의 swap도 참고) 예외 안전성을 확보하자
  • 7. Inline함수는 호출문을 함수 본체로 바꿔치기 한다. 함수호출 시 오버헤드가 없다. 컴파일러가 문맥별 최적화를 해줄 수 있다. But 메모리가 부족한 환경에서 쓰면 성능이 떨어진다. 컴파일러 선에서 무시할 수 있다. So, 작은 함수에 사용하자.(함수 호출 오버헤드만큼 작은..) 암시적인 방법 : 선언부에서 정의까지, int age() const { return value; } 명시적인 방법 : 정의 앞에 inline 키워드 붙이기. 가상함수 호출은 안됨 : inline은 컴파일러가 하는 데, 가상함수 호출은 runtime에 하니까 생성자, 소멸자에는 쓰지 말 것 : 컴파일러가 변수나 부모 클래스의 생성자도 실행하는 부분을 슬쩍 끼워넣을텐데 그 모든 것이 inline으로 만들어져야 함 Inline함수는 이해하고 사용하자
  • 8. 정의부에 대한 의존성을 선언부에 대한 의존성으로 포인터, 참조자에 대해서는 클래스 전방 선언으로 의존도를 줄일 수 있다. (실제 객체의 경우 컴파일 할 때 컴파일러가 그 크기를 알아야 하는데 껍데기만 있는 전방선언 클래스로는 알 수 없음.) 핸들 클래스 이용(pimpl관용구 사용) person이라는 선언부를 위한 클래스와 personImpl이라는 정의부를 위한 클래스 두 개로 쪼갬 선언부 클래스와 구현부 클래스는 함수가 동일, 선언부 멤버 변수로 구현부 클래스를 포인터로 가짐, 구현부는 실제 값들을 가짐. 선언부 함수들의 구현은 구현부 함수들을 호출하는 걸로. 생성자에서는 pimpl포인터 초기화 사용자는 person만 include하면 됨, 이때 person이 바로 핸들 클래스 인터페이스 클래스 (팩토리 함수 이용) person이라는 인터페이스 클래스와 이를 상속받은 realPerson 두 클래스로 구현 person에서는 필요한 함수들을 순수 가상 함수로 선언, 팩토리 함수인 create을 구현 static create()함수는 person 포인터형에 realPerson을 담아서 제공. 파일 사이의 컴파일 의존성을 최대로 줄이자!!
  • 9. 상속, 그리고 객체 지향 설계
  • 10. public 상속은 is-a 관계다. 즉, 자식 클래스는 부모가 될 수 있어도 부모 클래스는 자식이 될 수 없다. ** private은 다르다!! public 상속 모형은 반드시 is-a를 따르도록 하자
  • 11. 부모와 자식 클래스에 동일한 이름의 함수가 있을 때, 자식 클래스의 객체는 해당 함수를 호출하기 위해 먼저 가까운 유효범위(자식 클래스)를 뒤지고 부모 클래스로 간다. 즉, 부모 클래스의 함수는 가려진다. 문제는 부모 클래스에 있는 동일 이름의 오버로딩된 다른 함수도 가려진다는 것. 이 때, using Base::mf1; 등으로 가려진 함수를 꺼내 쓸 수 있다. 전달 함수로 꺼낼 수도 있음 상속된 이름을 숨기는 일은 피하자
  • 12. 순수 가상 함수를 선언하는 것은 인터페이스만 물려주려는 것 가상 함수를 선언하는 것은 인터페이스와 그 함수의 기본 구현 형태를 물려주려는 것. : 상속받은 함수만의 구현 형태가 없다면 기본 구현 형태를 써도 좋다. ** 순수 가상함수의 정의부분을 만들어 두고 자식 클래스에서 사용하는 방법도 있다. 비가상 함수를 선언하는 것은 인터페이스와 구현을 둘 다 물려주려는 것. : 이 함수는 재정의 하지 마라. 이 형태로 써라!! 상속 시 주의할 점 상속관계가 생긴다면 기본 클래스에는 최소한 가상 함수가 하나는 있을 것이다.(소멸자라도..) 모든 함수를 가상 함수로 만드는 것도 좋지 않다.(자신감이 없나? 하는 느낌을 줄 수도!!) 인터페이스 상속과 구현 상속의 차이를 제대로 구별하자
  • 13. NVI (비가상 함수 인터페이스) public : healthValue()는 private : virtual doHealthValue()를 호출한다. 여기서 healthValue가 인터페이스로 사용되며 wrapper라 부른다. wrapper를 통해서 doHealthValue()가 언제 실행될 지를 정하고 각 파생클래스에서는 doHealthValue()의 정의를 구현한다. ** 여기서 doHealthValue는 protected일 수도 있다.(파생클래스에서 기본 구현함수를 쓸 때) 함수 포인터로 구현한 전략 외부에 함수를 만들고 클래스 내부에서 함수 포인터를 이용 클래스 객체 자신을 매개변수로 하 여 기능을 수행하는 방법. 함수 포인터에 대한 개념공부가 더 필요할 듯 tr1::function 도 함수포인터를 제공해준다. 전략 패턴 사용 특정 기능 수행만 전담으로 하는 클래스를 외부에 만들고 원래 클래스가 그 클래스에 대한 객 체를 가리키는 포인터를 들고 있게 하는 방법, 포인터는 생성자에서 초기화. 가상 함수대신 쓸 것도 생각해보자
  • 14. 비가상 함수를 파생클래스에서 재정의하면 부모 클래스형 포인터에서 자식 클래스 객체를 가 리킬 경우 부모 클래스의 비가상함수가 호출된다. virtual이 아니니깐 상속받은 비가상 함수는 절대 재정의 하지 말자 상속받은 비가상 함수를 파생클래스에서 재정의하는 것은 금물
  • 15. 상속받은 함수를 재정의 한다는 건 일단 가상 함수만 가능하다. 문제는 기본 매개변수 값은 정적으로 바인딩되고 가상 함수는 동적으로 바인딩 된다는 것. 따라서 부모 클래스 형 포인터로 자식 클래스 객체를 가리킬 때, 부모 클래스의 매개변수를 이용해서 자식 클래스의 함수를 호출하게 된다. 상속받은 함수의 기본 매개변수 값은 절대로 재정의 하지 말자
  • 16. 어떤 클래스가 다른 클래스의 객체를 멤버 변수로 가지고 있을 때, 이를 객체 합성이라 한다. 객체 합성은 두 가지 측면에서 접근할 수 있는데, 현실에 있는 사물을 본 뜬 응용영역에서는 has-a 측면으로 접근하고 시스템 구현을 위한 구현영역에서는 is-implemented-interm-of 측면에서 접근하자. std::list로 set을 구현할 때, 이를 상속받는 것이 아니라 객체 합성하여 내부적으로 접근해야.. has-a 혹은 is-implemented-interm-of 를 모형화할 때는 객체 합성을 사용하자
  • 17. private 상속은 is-implemented-in-terms-of 를 의미한다. 객체 합성과 달리 private상속은 공백 기본 클래스 최적화를 활성화 할 수 있다. private상속은 심사숙고해서 구현하자
  • 18. 다중 상속은 모호성 문제를 일으킬 수 있다. 따라서 가상 상속을 활용하면 좋다. 연산 복잡도를 줄이기 위해 가상 상속 기본 클래스에는 데이터를 두지 말자. 하나는 인터페이스를 하나는 구현을 돕는 private 상속을 이용하는 것이 적법하다. 다중 상속은 심사숙고해서 구현하자