**try, catch
int main()
{
int iNum1 = 0, iNum2 = 0;
cin>>iNum1>>iNum2;
try
{
if(!iNum2) throw iNum2;
cout<<iNum/iNum2;
}
catch(int)
{
cout<<"Wrong"<<endl;
}
}**auto
class Obj
{
//
}
auto a = true; //bool
auto b = 'A'; //char
auto c = "abc";//const char *
auto d = 10; //int
auto e = 4.3f; //float
auto f = new Obj;//Obj*- 주로 STL 컨테이너와 같이 사용됨
vector<int> vecInt;
vecInt.push_back(2);
vecInt.push_back(2);
vecInt.push_back(2);
//auto가 저절로 자료형을 추론함
auto iter = vecInt.begin()**범위 기반 for문
- C#, java에서 먼저 제공,
- 제공하는 자료의 개수 만큼만 for문이 동작
- 컨테이너의 값이 복사되어서 전달됨
- &를 사용하여 컨테이너 원소 값에 직접 접근 할 수 있음
int iArr[5] = {1,2,3,4,5};
for(int i: iArr)
{
cout << i << endl;
}
for(auto i : vecInt) //vector의 원래 원소 변경 x
{
i+=1;
}
for(auto& i : vecInt)
{
i+=1;
}
map<int,int> mapInt;
for(auto i : mapInt) //i는 pair 객체
{
cout << i.first << i.second << endl;
}**유니폼 초기화
- 중괄호 식을 이용한 초기화 문법을 간략하게 표현하는 방법
struct tagInfo
{
int x;
int y;
}
class CObj
{
public:
CObj(tagInfo _tInfo)m_tInfo(_tInfo);
void Render();
void getData() {return tagInfo{10,20}}
private:
tagInfo m_tInfo;
}
int iArr[5]{1,2,3,4,5};
tagInfo tInfo{10, 20};
CObj obj({10,20}) //적절한 생성자가 있다면 가능!
vector<int> vecInt{1,2,3,4,5};
map<int,int> mapInt{{1,100}, {2,200}, {3,300}};**람다식
- 함수 객체를 대체하기 위한 문법
- 이름이 없는 inline 함수
[](){}형태[]: 람다 소개자, 캡처절. 컴파일러가 람다식인 것을 인지(): 파라미터 지정자. 일반 함수의 파라미터와 동일{}: 람다 몸체. 일반 함수의 몸체와 동일- 이름이 없는 함수이기 때문에 오버로딩이라는 개념이 없음.
[](){cout<<"hello world"} //그냥 사용시 호출 x
[](){cout<<"hello world"}()//호출 연산자를 사용해야 함
[](int i){cout << i << endl;}(100) //실행 100
//묵시적 반환
int iRes=[](int Dst, int Src){return Dst+Src}(10,20)
//명시적 반환
int iRes=[](int Dst, int Src)->int{return Dst+Src}(10,20);**캡처절
- 함수 외부의 변수들을 람다식 내부에서 사용하는 것
- 복사 방식 : 사본을 만들어서 값만 가져오는 행위(const 성격)
- 참조 방식 : 원본을 참조하는 행위
- 사본의 const 성격을 제거 하기 위해서 mutable 키워드 사용 가능
- static 변수, 전역변수, 클래스의 멤버 변수는 캡처 불가(데이터 영역)
**조건자로서의 람다식
//예제1
vector<int> vecInt{ 10, 20, 30, 40, 50 };
for_each(vecInt.begin(), vecInt.end(),
[](int n)
{
cout << n << endl;
});
//예제2
vector<int> vecInt{ 10, 20, 33, 40, 50 };
auto iter = find_if(vecInt.begin(), vecInt.end(),
[](int n)->bool
{
return 0 != (n % 2);
});
cout << *iter << endl;
//예제3
int iEvenSum(0), iOddSum(0);
vector<int> vecInt{ 1,2,3,4,5 };
for_each(vecInt.begin(), vecInt.end(), [&iEvenSum, &iOddSum](int n)
{
if (0 == n % 2)
iEvenSum += n;
else
iOddSum += n;
});
cout << iEvenSum << endl;
cout << iOddSum << endl;**R-Value 레퍼런스
class CObj
{
public:
CObj():m_iX(0),m_iY(0){}
CObj(int &X, int &Y):m_iX(X), m_iY(Y){}
private:
int m_iX;
int m_iY;
}
CObj* Create(int& X, int &Y)
{
return new CObj(X,Y);
}
CObj* Create2(int&& X, int&& Y) //r-value 레퍼런스를 매개변수로 받음
{
return new CObj(X,Y);
}
int main()
{
//불가능 !! r-value를 l-value를 받는 함수에 전달 할 수 없음
CObj* ptr = Create(10,20)
//가능!
CObj* ptr2 = Create2(10,20)
}**이동 생성자
- 원본을 사본으로 이전 시켜 생성하는 생성자, 명시적인 구현이 있어야 함
- 복사 생성보다 속도가 월등히 빠름
class CMyClass
{
private:
int* m_pArr;
int m_iSize;
public:
CMyClass(int iSize):m_iSize(iSize), m_pArr(new int[iSize]){}
CMyClass(const CMyClass& _ref)
{
m_iSize=_ref.m_iSize;
m_pArr = new int[_ref.m_iSize];
memcpy(//메모리 복사)
}
CMyClass(CMyClass&& _ref) //이동 생성자
{
m_iSize = _ref.m_iSize;
m_pArr = _ref.m_pArr;
_ref.m_pArr = nullptr //소유권 이전
}
}
int main()
{
CMyClass test1(10000);
CMyClass test2(test1); //복사 생성자 호출!
CMyClass test3(std::move(test1));
//move() : r-value로 캐스팅하는 함수, 이동 생성자 호출!
}