Hyun2and
인프런 C++ 프로그래밍 입문 : Modern C++ 본문
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
'공부엔 끝이없다 > 인프런 C++' 카테고리의 다른 글
인프런 C++ 프로그래밍 입문 : 객체지향 (0) | 2023.02.20 |
---|
Comments