C++ 스킬 35: typename과 class 키워드의 차이를 이해하자

 

C++ 스킬 36: 매개변수에 독립적인 코드는 템플릿으로부터 분리시키자

 

C++ 스킬 37: 타입 변환이 바람직할 경우에는 비멤버 함수를 클래스 템플릿 안에 정의해 두자

 

C++ 스킬 38: 특성 정보 클래스를 만들 때 오버로딩을 사용하는 방법이 있다.

 

C++ 스킬 39: 템플릿 메타 프로그래밍 (template metaprogramming : TMP) 을 알아두자

 

'읽은 책 > Effective C++' 카테고리의 다른 글

10. 상속  (0) 2022.04.27
9. 구현  (0) 2022.04.27
8. 소프트웨어 설계  (0) 2022.04.27
7. 자원관리 클래스와 스마트 포인터  (0) 2022.04.27
6. 대입 연산자  (0) 2022.04.27

 

C++스킬 27: public 상속 모형은 반드시 is-a 를 따르도록 만들자 (A는 B의 일종이다.)

 

C++스킬 28: 상속된 이름을 숨기는 일은 피하자

 

C++ 스킬 29: 인터페이스 상속과 구현 상속의 차이를 제대로 구별하자

 

C++ 스킬 30: 가상 함수 대신 쓸수 있는 다양한 패턴들

 

C++ 스킬 31: 가상 함수를 재정의 할때 기본 매개변수 값은 그대로 두자

 

C++ 스킬 32: is-implemented-in-terms-of 의 구현 방법(private 상속, 객체 합성)

 

C++ 스킬 33: 공백 기본 클래스 최적화(empty base optimaizaion : EBO) 기법 사용 방법

 

C++ 스킬 34: 다중 상속은 조심하자

 

'읽은 책 > Effective C++' 카테고리의 다른 글

11. 템플릿  (0) 2022.04.27
9. 구현  (0) 2022.04.27
8. 소프트웨어 설계  (0) 2022.04.27
7. 자원관리 클래스와 스마트 포인터  (0) 2022.04.27
6. 대입 연산자  (0) 2022.04.27

 

C++ 스킬 22: 변수 정의는 늦출 수 있는 데까지 늦추자

 

C++ 스킬 23: C 스타일의 캐스팅보다는 C++ 스타일의 캐스트를 사용하자.

캐스팅은 적게 사용할수록 좋다.

특히 dynamic_cast는 비용이 크므로 성능이 민감한 코드에서는 호출을 피하자.

 

C++ 스킬 24: 예외 안정성을 확보하자

ㄴ 자원 관리 클래스 사용하기 (스마트 포인터)

ㄴ Copy and swap 방식으로 객체를 수정하기 (swap은 예외를 던지지 않는 연산 내부에서 수행)

 

C++ 스킬 25: inline 함수를 활용하자

ㄴ 인라인 함수는 함수 호출 비용을 면제해준다.

ㄴ 인라인 함수는 대체로 헤더 파일에 들어 있게 만들자. 대부분의 빌드 환경에서 인라인을 컴파일 도중에 수행하기 때문에

ㄴ inline을 붙여도 inline이 될지 안될지는 컴파일러가 결정한다. 반복문이 있거나 재귀함수이거나 가상 함수 등은 인라인화 해주지 않는다.

 

C++ 스킬 26: 파일 사이의 컴파일 의존성을 최대로 줄이자

ㄴ 정의 대신에 선언에 의존하게 만들자

ㄴ 1. 핸들 클래스 사용하기

ㄴ 2. 인터페이스 클래스 사용하기

'읽은 책 > Effective C++' 카테고리의 다른 글

11. 템플릿  (0) 2022.04.27
10. 상속  (0) 2022.04.27
8. 소프트웨어 설계  (0) 2022.04.27
7. 자원관리 클래스와 스마트 포인터  (0) 2022.04.27
6. 대입 연산자  (0) 2022.04.27

 

 

C++ 스킬 15: 인터페이스 설계는 제대로 쓰기엔 쉽게 엉터리로 쓰기엔 어렵게 하자

 

C++ 스킬 16: 효과적인 클래스 설계를 위해 고려해야 할 부분들

1. 복사 생성자, 대입 생성자를 어떻게 둘 것인가.
2. 객체 생성과 소멸을 어떻게 할 것인가. (팩토리 함수, 직접 할당 해제)
3. 만든 클래스를 상속 시킨다고 하면 가상 함수를 어떻게 설정한 것인가.. (소멸자 등)
4. 암시적 명시적 타입변환을 허용할 것인가 (암시적: 타입 변환 연산자 operator T 생성) (명시적: 해당 변환을 하는 별도의 함수)
5. 예외 안정성, 자원 사용을 보장할 수 있는가

 

C++ 스킬 17: 값에 의한 전달 보다는 상수객체 참조자 (const &) 에 의한 전달 방식을 택하자

함수의 인자로 참조자를 사용하면 복사 생성자로 인해 새로 만들어지는 객체 같은 것이 없기 때문에 호출되는 생성자, 소멸자가 없어진다.

const는 호출부에서 전달한 객체가 바뀌지 않을 것이라는 보장을 해준다.

 

복사 손실 문제도 해결할 수 있는 장점이 있다.

ㄴ 파생 클래스 객체가 기본 클래스 객체로서 전달될 때 값으로 객체를 전달하면 기본 클래스의 복사 생성자가 호출되고, 파생 클래스 객체로 동작하게 해 주는 특징이 사라진다. (파생 클래스의 함수를 호출할 수 없다)

 

C++ 스킬 18: 지역 스택 객체에 대한 포인터나 참조자, 힙에 할당한 객체에 대한 참조자, 지역 정적 객체에 대한 포인터나 참조자를 반환하는 일은 그런 객체가 두 개 이상 필요해질 가능성이 있다면 하지말자 ( 메모리 누수와 비정상동작의 위험이 있다.) 

 

C++ 스킬 19: 멤버 함수 몇 개를 내부에서 호출하는 함수는 클래스 밖에서 선언하자. (비멤버 함수로 다른 헤더의 네임스페이스 같은 곳에 )

 

C++ 스킬 20: 어떤 함수에 들어가는 모든 매개변수 (this 포인터가 가리키는 객체 포함)에 대해 타입 변환을 해 줄 필요가 있다면 그 함수는 비멤버여야 한다. (operator* 의 교환 법칙)

예를 들어 연산 결과 (객체 * 2) 와 (2 * 객체)를 모두 처리하기 위해서는 operator* 멤버 함수를 사용할 수 없다. 비멤버 함수를 사용해야 한다.

 

C++ 스킬 21: std:swap이 느리게 동작할 여지가 있다면 swap 멤버함수를 제공하자

(클래스 템플릿의 경우) 비멤버 std::swap 함수를 std 네임스페이스가 아닌 다른 네임스페이스에 특수화하는 방법

멤버 함수로 swap을 정의하고 swap 안에서 std::swap을 사용하여 내부 포인터를 swap하는 방법

'읽은 책 > Effective C++' 카테고리의 다른 글

10. 상속  (0) 2022.04.27
9. 구현  (0) 2022.04.27
7. 자원관리 클래스와 스마트 포인터  (0) 2022.04.27
6. 대입 연산자  (0) 2022.04.27
5. 소멸자  (0) 2022.04.27

 

C++ 스킬11: 메모리 할당과 해제는 객체의 생성자와 소멸자에 맡기고 자원 관리 클래스 (스마트 포인터와 같은)를 사용해 메모리 누수의 가능성을 줄이자.

 

C++ 스킬12: 자원 관리 클래스에서 관리되는 자원은 외부에서 접근할 수 있도록 하자.

(스마트 포인터의 get() 함수)

 

C++ 스킬13: new와 delete를 사용할 때는 형태를 반드시 맞추자

 

C++ 스킬14: new로 생성한 객체를 스마트포인터에 저장하는 코드는 별도의 한 문장으로 만들자.

ㄴ 자원이 new로 생성되는 시점과 생성된 자원이 자원 관리 객체로 넘어가는 시점 사이에 예외가 끼어들지 못하게 된다.

'읽은 책 > Effective C++' 카테고리의 다른 글

9. 구현  (0) 2022.04.27
8. 소프트웨어 설계  (0) 2022.04.27
6. 대입 연산자  (0) 2022.04.27
5. 소멸자  (0) 2022.04.27
4. 컴파일러가 자동으로 만들어내는 함수 관리  (0) 2022.04.27

C++ 스킬8: 대입 연산자는 *this의 참조자를 반환하게 하자. (관례)

A = B = C 와 같이 쓸 수 있다.

 

C++ 스킬9: operator=에서는 자기대입에 대한 처리가 빠지지 않도록 하자

자원 관리 용도로 사용된 객체 (자원을 가리키는 원시 포인터를 멤버로 갖는 클래스)의 복사 대입 연산자를 구현할 때

왼쪽 객체(this)의 포인터를 delete하고 포인터가 오른쪽 객체(rhs) 의 자원을 가리키도록 하는데, 그 전에 this와 &rhs를 비교하여 같다면 아무 행동도 하지 않게 만들어야 한다.

 

예외 안정성, 자기대입 안정성을 동시에 가진 operator=를 구현하는 방법

복사 대입 연산자는 인자를 값으로 취하도록 선언하는 것이 가능하기 때문에

객체를 값으로 받은(사본이 생김) 다음 this와 swap하여 구현할 수 있다.

 

C++ 스킬10: 파생 클래스에서의 복사 생성자와 복사 대입 연산자 함수 안에서 기본 클래스의 복사 생성자와 복사 대입 연산자를 호출하자.

 

파생 클래스의 복사 생성자 -> 기반 클래스의 복사 생성자 호출

파생 클래스의 복사 대입 생성자 -> 기반 클래스의 복사 대입 생성자 호출

'읽은 책 > Effective C++' 카테고리의 다른 글

8. 소프트웨어 설계  (0) 2022.04.27
7. 자원관리 클래스와 스마트 포인터  (0) 2022.04.27
5. 소멸자  (0) 2022.04.27
4. 컴파일러가 자동으로 만들어내는 함수 관리  (0) 2022.04.27
3. 초기화  (0) 2022.04.27

 

 

C++ 스킬5: 다형성을 가진 기본 클래스에서는 소멸자를 반드시 가상 소멸자로 선언하자

 

어떤 클래스를 인스턴스를 만들지 못하는 클래스(추상 클래스)로 만들고 싶은데 마땅히 넣을 만한 순수 가상 함수가 없는 경우 순수 가상 소멸자를 선언하면 된다. (+ 소멸자의 정의도 필요하다)

 

기반 클래스로 설계되지 않았거나 다형성을 갖도록 설계되지 않은 클래스에는 가상 소멸자를 선언하지 말아야 한다.

 

C++ 스킬6: 소멸자에서 예외가 발생할 가능성을 최대한 낮추는 것이 좋다.

ㄴ 소멸자 밖으로 예외가 빠져나가지 않도록 해야 한다.

 

C++ 스킬7: 생성자와 소멸자에서는 가상 함수를 호출하지 말자.

 

C++ 스킬4: 컴파일러에 의해 만들어진 함수가 필요 없으면 이들의 사용을 금지하자

 

클래스 멤버에 참조자나 상수가 있다면 멤버 초기화 리스트를 반드시 사용해야 하고, 복사 대입 생성자가 자동으로 생성되지 않는다.

'읽은 책 > Effective C++' 카테고리의 다른 글

6. 대입 연산자  (0) 2022.04.27
5. 소멸자  (0) 2022.04.27
3. 초기화  (0) 2022.04.27
2. 상수, 인라인 함수, mutable  (0) 2022.04.27
1. 생성자, 복사 대입 연산자, 복사 생성자  (0) 2022.04.27

+ Recent posts