3월, 2020의 게시물 표시

[Effective C++] new 및 delete 를 작성할 때 따라야 할 기존의 관례를 잘 알아 두자

항목 51 : new 및 delete 를 작성할 때 따라야 할 기존의 관례를 잘 알아 두자

[Effective C++] new 및 delete 를 언제 바꿔야 좋은 소리를 들을지를 파악해 두자

항목 50 : new 및 delete 를 언제 바꿔야 좋은 소리를 들을지를 파악해 두자

[Effective C++] new 처리자의 동작 원리를 제대로 이해하자

항목 49 : new 처리자의 동작 원리를 제대로 이해하자

[Effective C++] 템플릿 메타 프로그래밍 하지 않겠는가

항목 48 : 템플릿 메타 프로그래밍 하지 않겠는가

[Effective C++] 타입에 대한 정보가 필요하다면 특성정보 클래스를 사용하자

항목 47 : 타입에 대한 정보가 필요하다면 특성정보 클래스를 사용하자

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

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

[Effective C++] "호환되는 모든 타입"을 받아들이는 데는 멤버 함수 템플릿이 직방!

항목 45 : "호환되는 모든 타입"을 받아들이는 데는 멤버 함수 템플릿이 직방!

[Effective C++] 매개변수에 독립적인 코드는 템플릿으로부터 분리시키자

항목 44 : 매개변수에 독립적인 코드는 템플릿으로부터 분리시키자

[Effective C++] 템플릿으로 만들어진 기본 클래스 안의 이름에 접근하는 방법을 알아두자

항목 43: 템플릿으로 만들어진 기본 클래스 안의 이름에 접근하는 방법을 알아두자

[Effective C++] typename 의 두 가지 의미를 제대로 파악하자

항목 42 : typename 의 두 가지 의미를 제대로 파악하자

[Effective C++] 템플릿 프로그래밍의 천릿길도 암시적 인터페이스와 컴파일 타임 다형성부터

항목 41 : 템플릿 프로그래밍의 천릿길도 암시적 인터페이스와 컴파일 타임 다형성부터

[Effective C++] 다중상속은 심사숙고해서 사용하자

항목 40 : 다중상속은 심사숙고해서 사용하자

[Effective C++] private 상속은 심사숙고해서 구사하자

항목 39 :  private 상속은 심사숙고해서 구사하자

[Effective C++] "has-a" 혹은 "is-implemented in terms of"(~는 ~를 써서 구현됨)를 모형화할 때는 객체 합성을 사용하자

항목 38 :  "has-a" 혹은 "is-implemented in terms of"(~는 ~를 써서 구현됨)를 모형화할 때는 객체 합성을 사용하자 소프트웨어 개발에서 영역(domain)은 두 가지로 나뉜다. 사람, 이동수단 등 실제 사물을 본 따서 만든 객체를 응용 영역(application domain), 버퍼, 뮤텍스, 탐색 트리 등 순수하게 시스템 구현만을 위한 인공물들을 구현 영역(implementation domain)에 속해있다고 부른다. 여기서 객체 합성이 응용 영역의 객체들 사이에서 일어나면 has-a 관계이다. 반면 구현 영역에서 일어나면 그 객체 합성의 의미는 ( is-implemented-in-terms-of ) 관계를 나타낸다. 써서 구현되는 관계 (is implemented in terms of) 형태의 설계 -> 특정 파생클래스와 기반클래스가 is-a 관계가 아니지만 , 파생클래스는 기반 클래스의 기능을 활용해서 구현된 것 참조 :  https://mokga.tistory.com/121

[Effective C++] 어떤 함수에 대해서도 상속받은 기본 매개변수 값은 절대로 재정의하지 말자

항목 37 : 어떤 함수에 대해서도 상속받은 기본 매개변수 값은 절대로 재정의하지 말자

[Effective C++] 가상 함수 대신 쓸 것들도 대신 생각해 두는 자세를 시시때때로 길러 두자

항목 35 : 가상 함수 대신 쓸 것들도 대신 생각해 두는 자세를 시시때때로 길러 두자

[Effective C++] 인터페이스 상속과 구현 상속의 차이를 제대로 파악하고 구별하자

항목 34 : 인터페이스 상속과 구현 상속의 차이를 제대로 파악하고 구별하자 . 인터페이스는 외부에서 해당 객체의 동작을 명령을 내리는 버튼과 같고 , 구현이란 특정 명령에 의해 어떻게 동작할지 나타내는 것 . 두 가지는 분명히 다르며 클래스 상속 관계를 설계할 때도 유념해야 할 것 순수 가상 함수를 선언하는 목적은 파생 클래스에게 함수의 인터페이스만을 물려주려는 것입니다 . 단순 가상 함수를 선언하는 목적은 파생 클래스로 하여금 함수의 인터페이스뿐만 아니라 그 함수의 기본 구현도 물려받게 하자는 것입니다 . 비가상 함수를 선언하는 목적은 파생 클래스가 함수 인터페이스와 더불어 그 함수의 필수적인 구현 (mandatory implementation) 을 물려받게 하는 것입니다 . 순수 가상 함수에도 정의를 제공할 수 있다 . 즉 순수 가상함수에도 기본 구현을 달아서 상속시킬 수 있다는 것 . 판단에 따라 인터페이스만을 상속시켜도 되고 , 인터페이스와 기본 구현을 함께 상속시킬 수도 있으며 , 아니면 인터페이스와 필수 구현을 상속시킬 수 있는 것입니다 . 클래스를 설계할 때 가장 기본적인 실수 2 개 : 모든 멤버 함수를 비가상 함수로 선언하는 것 . ( 소멸자 부분이 골칫거리가 될 수 있다 ), 혹은 모든 멤버 함수를 가상함수로 선언하는 것 . 참조 :  https://www.ikpil.com/485

[Effective C++] 상속된 이름을 숨기는 일을 피하자

항목 33: 상속된 이름을 숨기는 일을 피하자

[Effective C++] 파일 사이의 컴파일 의존성을 최대로 줄이자

항목 31 : 파일 사이의 컴파일 의존성을 최대로 줄이자

[Effective C++] 인라인 함수는 미주알고주알 따져서 이해해 두자

항목 30 : 인라인 함수는 미주알고주알 따져서 이해해 두자

[Effective C++] 예외 안전성이 확보되는 그날 위해 싸우고 또 싸우자

항목 29 : 예외 안전성이 확보되는 그날 위해 싸우고 또 싸우자

[Effective C++] 내부에서 사용하는 객체에 대한 '핸들'을 반환하는 코드는 되도록 피하자

항목 28 : 내부에서 사용하는 객체에 대한 '핸들'을 반환하는 코드는 되도록 피하자

[Effective C++] 캐스팅은 절약, 또 절약! 잊지 말자

항목 27 : 캐스팅은 절약, 또 절약! 잊지 말자

[Effective C++] 변수 정의는 늦출 수 있는 데까지 늦추는 근성을 발휘하자

항목 26 : 변수 정의는 늦출 수 있는 데까지 늦추는 근성을 발휘하자

[Effective C++] 예외를 던지지 않는 swap에 대한 지원도 생각해 보자

항목 25 : 예외를 던지지 않는 swap에 대한 지원도 생각해 보자 참조 :  https://wikidocs.net/652

[Effective C++] 타입 변환이 '모든 매개변수'에 대해 적용되어야 한다면 비멤버 함수를 선언하자

항목 24 : 타입 변환이 '모든 매개변수'에 대해 적용되어야 한다면 비멤버 함수를 선언하자

[Effective C++] 멤버 함수보다는 비멤버 비프렌드 함수와 더 가까워지자

항목 23 : 멤버 함수보다는 비멤버 비프렌드 함수와 더 가까워지자

[Effective C++] 함수에서 객체를 반환해야 할 경우에 참조자를 반환하려고 들지 말자

항목 21 : 함수에서 객체를 반환해야 할 경우에 참조자를 반환하려고 들지 말자

[Effective C++] '값에 의한 전달' 보다는 '상수객체 참조자에 의한 전달' 방식을 택하는 편이 대개 낫다

항목 20 : '값에 의한 전달' 보다는 '상수객체 참조자에 의한 전달' 방식을 택하는 편이 대개 낫다

클래스 설계는 타입 설계와 똑같이 하자

항목 19 : 클래스 설계는 타입 설계와 똑같이 하자 새로 정의한 타입의 객체 생성 및 소멸은 어떻게 이루어져야 하는가? 객체 초기화는 객체 대입과 어떻게 달라야 하는가? 새로운 타입으로 만든 객체가 값에 의해 전달되는 경우에 어떤 의미를 줄 것인가? (보통 이쪽은 복사생성자가 관여한다) 새로운 타입이 가질 수 있는 적법한 값에 대한 제약은 무엇으로 잡을 것인가? 기존의 클래스 상속 계통망(inheritance graph)에 맞출 것인가? 어떤 종류의 타입 변환을 허용할 것인가? 어떤 연산자와 함수를 두어야 의미가 있을까? 표준 함수들 중 어떤 것을 허용하지 말 것인가? 새로운 타입의 멤버에 대한 접근권한을 어느 쪽에 줄 것인가? '선언되지 않은 인터페이스'로 무엇을 둘 것인가? 새로 만드는 타입이 얼마나 일반적인가? 정말로 꼭 필요한 타입인가? 참조 :  https://kkojabee.tistory.com/entry/Effective-C-Item-19-Treat-class-design-as-type-design

인터페이스 설계는 제대로 쓰기엔 쉽게, 엉터리로 쓰기엔 어렵게 하자

인터페이스 설계는 제대로 쓰기엔 쉽게, 엉터리로 쓰기엔 어렵게 하자

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

항목 17 : new로 생성한 객체를 스마트 포인터에 저장하는 코드는 별도의 한 문장으로 만들자

new 및 delete를 사용할 때는 형태를 반드시 맞추자

항목 16 : new 및 delete를 사용할 때는 형태를 반드시 맞추자

자원 관리 클래스에서 관리되는 자원은 외부에서 접근할 수 있도록 하자

항목 14 : 자원 관리 클래스에서 관리되는 자원은 외부에서 접근할 수 있도록 하자

[C++] 우측값 레퍼런스를 어셈블리로 보면??

이미지
prvalue 와 xvalue 의 차이점이 잘 이해가 안되서 살짝 공부해보기로 우측값은 실체가 없는 값이라는 설명을 들은 적이 있지만, 컴파일러의 입장에서는 다른 듯 하다. 7 번째 라인을 보면 스택 메모리의  ebp-78h 위치에 (ebp 는 스택의 시작 주소, 즉 시작지점에서 78번째 아래 있는 부분) 5 값을 저장해두고 있으며, 해당 부분의 주소를 우측값 레퍼런스에 넘겨주고 있다. 우측값 참조되는 값은 분명 메모리 상에 존재하지만 그것을 프로그래머는 알 수 없는 셈 우측값 레퍼런스와 관련해서 빼놓을 수 없는 std::move 명령어는 어떨까. 디스어셈블리로 본다면 그저 넘겨받은 인자의 실 주소값을 그대로 넘겨주고 있다. 사실상 타입변환의 의미만 존재하고 메모리 상에서는 아무 일도 없다.  다시 생각해본다면 prvalue, xvalue 의 차이점을 이렇게 볼 수 있을 것 같다.  전체 rvalue 부류에서 prvalue는 프로그래머 입장에서 그 실체 혹은 메모리의 어디에 있는지 확실히 파악할 수 없는 값.  (리터럴 Int, Char, 값 타입을 반환하는 함수의 반환값, 특정 연산의 결과로 임시로 만들어진 값 등)  마찬가지로 rvalue 에서 xvalue 란 프로그래머 입장에서 그 실체에 대해 알고 잆는 값 {    int a = 1;    int&& rv = std::move(a); // 우측값인 동시에 우리는 a 에 대해 알고 있다. }  참조 :  https://stackoverflow.com/questions/36827900/what-makes-moving-objects-faster-than-copying https://www.learncpp.com/cpp-tutorial/15-3-move-constructors-and-move-assignment/

컴파일러 Copy Elision

참조 :  https://kldp.org/node/160274 https://jacking75.github.io/cpp_copy_elision/