Hyun2and

인프런 C++ 프로그래밍 입문 : Modern C++ 본문

공부엔 끝이없다/인프런 C++

인프런 C++ 프로그래밍 입문 : Modern C++

혀니앤 2023. 2. 20. 21:53
728x90

 

[인프런] C++ 프로그래밍 입문 을 보고 정리하는 글

 

1.auto

  • 초기화하는 값을 기반으로 형태를 맞추어 변수의 타입을 자동으로 지정해준다
  • Type deduction : 컴파일러가 타입을 추론함
  • 기본 auto  const, & 무시한다
int& reference = a;
const int cat = a;

auto test1 = reference; // int&가 되어야하지만 int
auto test2 = cat; //const int 가 되어야하지만 int
  • auto&  정의하여 포인터임을 지정한다

 

auto  쓰는 상황

  • for 문에서 iterator  정의해야 하는 경우, 정의하지 않고 바로 사용한다
  • 코드가 너무 길어지는 경우

 

 


 

2. 중괄호 초기화

  • 중괄호를 사용하여 값을 초기화해주게 된다
  • 변수의 초기화 
int a = 0 ;
int b { 0 };

 

 

  • 클래스의 초기화
     
Knight k2 = k1;
Knight k3{ k2 };

 

중괄호 초기화의 장점

  • 컨테이너 초기화
  • 원래는 기본 배열만 중괄호를 이용해 초기화했지만 이제는 vector와 같은 컨테이너에서도 가능하다
int arr[] = {1,2,3,4};
vector<int> arr{1,2,3,4};
  • 축소 변환이 방지된다

 

단점

  • initializer_list 를 사용해서 생성자에 파라미터를 넣어 제약없이 받는다

 


3.nullptr

  • 2000년도 초반에서는 0, null 값을 사용함
  • 함수 오버로딩과 관련있음

 

 사용하나?

  • 오동작을 막을 수 있다.
  • 코드의 가독성이 높아진다
auto knight = FindKnight( );
if( knight == nullptr )
{
.… //auto 를 사용했을 때, 타입을 추측할 수 없지만, nullptr 과 비교함으로써 포인터를 받았음을 추측가능함
}

 


 

4.Using

  • typedef 대신 사용할 수 있다
  • 직관적이다
  • 템플릿을 이용할 수 있음
  • typedef 는 템플릿 사용 불가능
     
template<typename T>
using List = std::vector<T>;
  • 기존의 typedef 활용법
     
template<typename T>
struct List2
{

  typedef std::list<T> type;
}

5. enum class

Enum

  • 가독성을 높이기 위해 사용한다
  • 지정하지 않으면 0부터 시작.  다음 값들은 이전  + 1 연속정수의 값을 갖는다

 

 

#define

  • # 들어가면 전처리 과정에서 쓰인다 (전처리->컴파일->링킹)
  • #define 변수 변수명
  • #define 함수 함수명
 
#define TEST cout<<"hello world!";​
  • 정말 define 으로 설정한 변수 위치에 뒤의 내용을 대신 넣는 것과 동일하다

 

Enum class (scoped enum)

  • enum 공간 관리에 용이함
  • enum 범위가 없이, 전역처럼 쓰임(unscoped enum)

-> enum 요소들을 명확한 이름으로 사용할  있게됨

  • 압묵적인 변환이 금지됨

 


6.delete

  • 특정 연산자를 사용하지 않고 싶을 때 해당 연산자를 삭제한다
     
  • 통상적으로 public 으로 정의한다
Class A {
public :
    void operator=(const Knights& k) = delete;
}

7.override

  • virtual 키워드를 통해 실제로 가지고 있는 타입을 기반으로 포인터를 사용한다
  • 자식 클래스에서 virtual 을 붙이지 않아도 동일한 이름의 함수는 가상함수가 됨
  • 최초의 함수인지, 부모의 함수인지를 표시할 수 있다
  • 자식 함수에서 const 를 붙이게되면 다른 함수로 인식한다
     
virtual void Attack() const
{
 //const 키워드를 붙임으로써 override 되지않는다
}
  • 부모, 자식 간의 키워드를 동일하게 정의해야한다

 

+ Final

  • 마지막으로 override 할 것이며, 자신을 상속받는 클래스들에서는 오버라이드할 수 없음

8. 오른값 참조 (rvalue reference)

왼값? 오른값?

  • lvalue (left value) : 단일식을 넘어서 계속 지속되는 개체
  • rvalue (right value) : lvalue 가 아닌 나머지 (임시 값, 열거형, 람다, i++ 등)
int a = 3 ; // a 는 대입이 가능한, 지속가능한 값이지만 3 같은 값은 임시로만 존재하는 값이다
 
  • 기존의 방법
 
void TestKnight_Copy(Knight knight) {  } // 설계가 방대하다면, class 를 복사해서 넘겨주는 것은 좋지 않다. 
void TestKnight_LValueRef(Knight& knight) {  } // rvalue를 인자로 넘길 수는 없다void TestKnight_ConstLVlaueRef(const Knight& knight) {    } // const 인 경우에만 rvalue를 인자로 넘길 수 있다

 

새로운 참조 방법

 
  • 호출하는 방법
void TestKnight_RValueRef(Knight&& knight){  } // 새롭게 생긴 방법
TestKnight_RValueRef(Knight());
TestKnight_RValueRef(static_cast<Knight&&>(k2));
  • 모두 같은 방법으로 작동하지만, 의미가 다르다 
     
void TestKnight_LValueRef(Knight& knight) {  } // 왼값 참조를 넘겼으므로, 원본을 넘겨줄테니 알아서 써라!
void TestKnight_ConstLVlaueRef(const Knight& knight) {    } // 원본을 주긴 주겠지만, 원본을 수정하면 안되고 읽기만 해라!
void TestKnight_RValueRef(Knight&& knight){  } // 원본을 줄거고, 읽기쓰기도 되고, 난 더이상 안쓸거다! 이동 대상이 되었음을 알려준다

 

쓰임

  • 원본을 유지하지 않고 날리는 경우에 쓰게 된다 (자주 쓰지는 않음)
k3 = std::move(k2); // 오른값 참조로 캐스팅해준다. k2는 더이상 유효하지 않은 이동 값이다.
 
  • 스마트포인터와 연결지어서, unique 포인터를 더이상 쓰지 않으려고 할 때 원본을 전달할 수 있다
std::unique_ptr<Knight> uptr2 = std::move(uptr1);

 

 

9. Forwarding Reference

  • 템플릿, auto를 사용하는 과정에서 형식 연역이 발생하는 경우
  • 왼값, 오른값 관계없이 동작하는 코드를 만들기
std::forward(param); //왼값이라면 복사하고, 오른쪽 참조라면 rvalue로 이동시킨다

 

 


 

10. 람다(lambda)

  • 기존의 문법으로 구현할 수 있는 것이기는 했다
  • 함수 객체를 빠르게 만드는 문법

람다 만드는 법

  • closure : 람다에 의해 만들어진 실행시점의 객체
auto isUniqueLamda = [](Item& item) { return item._rarity == Rarity::Unique; } ;

 

  • [ ] capture(캡쳐) : 함수 객체 내부에 변수를 저장하는 개념
  • 값 복사 =, 참조 &
     
int itemid = 4;
auto findByItemLanme = [&](Item& item) { return item=_itemId == itemid; } ; // 지정하지 않으면 값 복사, 참조는 & 방식

 

  • 변수마다 캡쳐 방식을 다르게해줄 수 있다
auto findByItem = [itemid, rarity, &type](Item& item){ } // 여러 개의 변수를 사용하고 싶다면, 이름 앞에 &를 넣어 써준다

 

728x90
Comments