전부 요약하면 끝도 없고


3ebcda2dabc236a14e81d2b628f1716a3d52e4ab


중요 핵심 부분만


10 표준 라이브러리는 모든 기능을 제공할 필요가 없다. 때로는 간단한 함수를 직접 작성하는 것만으로도 문제를 해결 할 수 있다.

예를 들어 make_Vector 함수같은게 그렇다. 아마도 C++ 미래버전에서는 Vector가 이러한 구성방식을 직접 지원할 수도 있을 것이다.


(표준 라이브러리가 발전함에 따라 사용자 정의 함수의 필요성이 줄어든다는 것을 암시)

(설명: make_Vector는 std::vector에서 여러값을 한번에 벡터에 추가할때 쓰임. )


0. 새로운 기능이라고 무조건 쓸려고 하지마라. 최신 기능과 향후 개발 방향은 어차피 관련 기술 문서를 참고하면 된다.

프로그래밍 언어의 궁극적 가치는 애플리케이션의 품질에 있다. 전체적으로 목표는 프로그래밍 언어를 써서 좋은 소프트웨어를 개발하는 것이다.



1. 리소스 관리

->우리는 사람들이 물건 반납보다 구입에 관심 있다는 것을 안다.

이 말뜻은 빌린 자원을 명시적으로 반환해야하지만, 반드시 일부는 놓치게되어있다.


그렇다면 리소스의 정의는 무엇인가?

-> 얻고 나서 해체되어야하는 모든 것이라고 정의함


이는 메모리, 문자열,파일 핸들, 소켓,스레드 핸들 등등 많은 것들을 말함


C++에서는 각 리소스에 해당 리소스의 라이프 사이클을 관리하는 핸들이 있어야한다.

이러한 (핸들) 매커니즘은 라이프 사이클을 엄격히 제어함으로써 구현됨


다음은 비야네가 주장하는 핵심원칙


1. 수동으로 리소스 해체 하지마라(애플리케이션 코드에, free(),delete 등의 리소스 해체 작업이 나타나지 않도록 코드를 짜라)


2. 리소스 핸들을 사용하라- 각 객체는 접근과 해제를 담당하는 핸들에 의해 관리되어야함


3. 스코프(범위,Scope)를 정해서 써라. -모든 리소스 핸들은 특정 스코프에 속하고, 스코프간에 전달되어야한다.


3db2c877abc236a14e81d2b628f1706f1d7c1e

(예시 코드를 내가 번역함)

(사실 RAII 원칙 자체가 C++ 핵심 개념이라 새삼 스럽긴함)

(RAII-> 리소스 획득 및 초기화)


(저 말 요약해서 이야기하자면 소멸자에서 리소스를 해체하면 free(),delete등을 호출할 필요가 없단 뜻)


C++의 기반은 생성자와 소멸자이다.

"생성자와 소멸자"


리소스 획득-> 생성자

리소스 반환->소멸자


비야네가 말하는 리소스 관리법


생성 - 처음 사용하기전 객체의 불변성의 유무를 설정하라

소멸- 마지막 사용한 후에, 리소스를 해체하라

복사- a=b는 a==b를 의미하고, 둘은 독립적 객체이다

이동 - 스코프 간에 리소스 소유권을 이동해라.


(이동 시맨틱을 활용해서, 스코프 간의 이동을 보장하란 말임. 스코프는 일반적으로 함수내부, 코드 블록 내부를 의미함. 따라서, C++에서 객체는 생성 스코프 내에서만 유효하고, 스코프를 벗어나면 소멸됨, C++11에서 도입된 리소스 소유권 매커니즘을 이용하라. 이 말인듯.)


이 매커니즘을 이용해야 신뢰성있는 안전한 코드를 짤 수 있다. 왜냐하면 리소스 관리를 프로그래머 기억력에 의존하지 않고, 언어 매커니즘이 보장하기때문


3. 헤더파일 포함 오더 문제


-> #include "a.h" 다음에 #include"b.h"를 쓰는 것은 순서를 바꿨을때 완전히 다른 결과를 배출 할 수 있었음


하지만 C++20에 도입된 모듈 매커니즘은 다르다.


3db2c874abc236a14e81d2b628f1776b620f

순서 상관없이 해도 문제 없다.


즉 import는 더 깨끗하고, 컴파일 속도 향상됨


즉 이제 include는 사용할 필요가 없다. 점차적으로 C 전처리기를 퇴출하는 것이 목표였는데 해냈다.

어쨌건 모듈 개선 후 속도가 더 빨라졌다고함


3db4c63eabc236a14e81d2b628f1756bb8b9d93f


4. 제네릭 프로그래밍 설명(이 부분은 너무 길어서 내가 생략함)



5. 최적화


양파원리


과도한 최적화를 피하라는 조언을 들어본 적 있지만, 과도한 최적화를 어떻게 피하는가?


인터페이스 설계부터 최적화를 고려해라


1.인터페이스 설계는 명확하게 정의되어야 한다.


2.타입 정보의 무결성을 유지해야 한다.


3.검사 및 최적화를 지원하기 위한 충분한 정보를 제공해야 한다.


4. 복잡도 관리: "간단한 일은 간단하게 처리하라!"


코드를 양파의 층으로 생각해 보라.

최적화나 특수한 경우를 처리할 때마다 우리는 양파의 한 층을 벗겨내야 할 수 있다

하지만 기억하라, 한 층씩 벗겨낼 때마다 눈물이 날 것이다.


왜냐하면 한 층씩 깊이 들어갈수록 더 많은 오류에 직면하게 되고, 더 많은 코드를 작성해야 하며, 코드를 이해하기도 더 어려워지기 때문.

그래서 정말로 필요하기 전까지는 추상화의 한 층을 벗겨내지 마라.

이것이 제가 '과도한 최적화를 피하라'는 조언에 대한 이해이다.

(그니까 과도하게 추상화를 벗겨내서 명시화 할 필요 없다는 말임)


(즉 요약하자면 가급적 추상화 계층은 유지하되,

정말 성능이 급하거나, 메모리를 다뤄야하는 극소수의 경우에만 껍질을 벗기라는 말. 껍질을 깍을때마다 코드가 복잡해지고 사람이 실수할 가능성이 커짐 ㅇㅇ)


비야네가 요약한 C++ 프로그래밍 모델



정적 타입 시스템: 내장 타입과 사용자 정의 타입을 동시에 지원


값 의미론과 참조 의미론 지원: 값 의미론과 참조 의미론을 모두 지원


통합된 리소스 관리 메커니즘 (RAII): 리소스 획득 즉 초기화(RAII)를 통해 리소스를 관리


효율적인 객체 지향 프로그래밍: 객체 지향 프로그래밍을 효율적으로 지원


유연하고 효율적인 제네릭 프로그래밍: 제네릭 프로그래밍을 유연하고 효율적으로 지원


컴파일 타임 프로그래밍: 컴파일 타임에 코드를 생성하고 실행


하드웨어 및 운영체제에 직접 접근: 하드웨어와 운영체제에 직접 접근


라이브러리를 통한 동시성 지원: 내부 명령어를 활용해서 동시성을 지원


C 전처리기의 최종 퇴출: C 전처리기를 점차적으로 퇴출시키는 게 목표