C++ 11 에 대해서 쉽게 알아봅시다 1부
-
Upload
gwangwhi-mah -
Category
Software
-
view
276 -
download
5
Transcript of C++ 11 에 대해서 쉽게 알아봅시다 1부
C++.. 어디까지 알고 계시나요?
우리가 가지고 할 교재
C++ 기초 플러스 6판C++ 의 정석
C++ 11을 알아봅시다
C++ 11
Modern C++ 11 이라고 함
언어가 우후죽순 생기는 중에 C++의 장점을 내세우고 효과적인 기능을 추가하여
만들어진 최신 기술 동향을 일컬음
14, 17등 업그레이드를 하고 있음
보통 C++ 11의 문법들은 Boost에서 나오는게 많음
이전의 C++ 들
새로운 자료형
데이터 타입 설명 사용예
long long (int) long long 정수. 표현 가능한 크기는 컴파일러에 따라 다르나 보통 8바이트
Long long ll = 14;
unsigned intunsigned short (int)unsigned long (int)unsigned long long (int)
0을 포함한 양수만 표현가능한 정수
unsigned int i = 2;
char16_t 16비트 문자 char16_t c16 = u’m’;
char32_t 32비트 문자 char32_t c32 = U’m’;
auto 컴파일러에 의해 자동으로타입이 정해지는 타입
auto i = 7; //자동으로 int형으로 변환
decltype(expt) “expr”이 나타내는 타입과같은 타입을 따르는 타입
int i = 7; decltype(i) j =8; j는 i의 타입을 따라 int 됨
새로운 자료형
엄격한 열거형
엄격한 열거타입 Enum Class
기존의 enum은 Type Safe 하지 않고, 기본적으로 정수 타입으로 취급을받기 때문에 서로 완전 별개인 열거 타입 간 비교 연산이 가능해짐에 따라C++ 11에서는 이러한 문제를 해결하기 위해 enum class가 만들어 졌다
E_Class는 타입 세이프 하기 때문에 열거 값이 다른 정수 타입 변수로 자동 캐스팅이 되지 않고 class 이름으로 Scope 되어있지 않으면 참조 불가능
enum class E_Class{
E_VALUE1,E_VALUE2 = 100,E_VALUE3
};
enum class E_Class : unsigned long{
E_VALUELONG1,E_VALUELONG2 = 100,E_VALUELONG3
};
범위 기반 반복문
Range Based For (구간 지정 루프)
Range Based For는 C++ 11에서 새로 도입된 반복문.리스트 순회하며 하는 작업등 객체 단위로 탐색할 때등 요긴하게 쓰일때 많음.begin(), end() 함수를 멤버로 가진 데이터 타입을 대상으로 함.
참고 : std::for_each 도 있습니다
[일반적인 Range Based For]
int arr[] = {1 ,2 ,3 ,4};
for(int i : arr){
i += 2;}
[C++ 11 Auto 사용]
vector<int> arr = {1 ,2 ,3 ,4};
for(auto i : arr){
i += 2;}
std::array
std::array
C++ 11에서는 std::array라는 새로운 컨테이너를 선보이고 있다.C 언어에서의 배열을 대체하는 안전한 배열 타입. std::array가 없을때는 std::vector을 사용하였다. std::array는 크기를 고정하지만 vector보다 overhead가 적다는 장점이있다.
#include <iostream>#include <array>int main(){
std::array<int, 3> arr = {9, 8, 7};std::cout << “array size = “ << arr.size() << endl;for(auto i : arr)
std::cout << i << std::endl;
return 0;}
Uniform Initializer
Uniform Initializer (유니폼 이니셜 라이저)
[변수 및 컨테이너 초기화]
int b {0};
std::vector<CMan> table1;table1.push_back(CMan(10, "1"));table1.push_back(CMan(20, "2"));table1.push_back(CMan(30, "3"));
std::vector<CMan> table2 = { {10, "1"}, {20, "2"}, {30, "3"} };
C++에서 기존 STL이나 클래스를 만들기 위해서는Vector의 경우에는 push_back을 이용해서 추가를 해주었고, 클래스의 경우에는 생성자를 사용해 만들어 주었음.하지만 이제 그럴 필요없이 {} 로 초기화가 가능함그것을 Uniform Initialization 이라고 함
[변수 및 컨테이너 초기화]
class CMan{public:CMan(int nValue, std::string str){std::cout << nValue << " " << str.c_str() << std::endl << std::endl;}~CMan(){}};CMan man1(10, "봵쇍");
Auto와 Decltype의응용
Auto 와 Decltype의 응용
template<typename T, typename Y>auto Add(T a, Y b) -> decltype (a + b)// -> : Alternative Function Syntax {return a + b;}
Template, Decltype, Auto, Alternative Function Syntax를 사용하여응용하는 방법, 이렇게 연산을 하게 되면 float와 int의 동시 연산이 가능해짐
Smart Pointer
Smart Pointer (스마트 포인터)
C++에도 자동으로 메모리를 관리해 주는 기능이 있다면??
Smart Pointer (스마트 포인터)
바로 여기, 있습니다!
Smart Pointer (스마트 포인터)
Java, C# 같은 언어는 Garbage Collection 기능이 있음
C++에도 일부 메모리를 관리 해주는 기능이 있으며,세계 각국의 개발자들이 만든 3rd party 라이브러리를 사용한다면 좀 더 강력한메모리 관리 기능을 사용할 수 있음.
하지만 이러한 기능도 완벽한 것이 아니기 때문에
본인이 실수 없이 오나벽한 코딩을 할 수 있고, 시간과 노력이 아깝지 않다면 직접 구현 하는게 좋다.
먼저 설명은 C++ 11의 Smart Pointer가 아니라 Smart Pointer의 전반적인설명이 들어갈 것이다.
소유권 독점 방식Smart Pointer,
auto_ptr [C++ 표준]
소유권 독점 방식 Smart Pointer, auto_ptr [C++ 표준]
#include <memory>using namespace std;class CTest{public:
inline int getValue() { return m_ivalue; }inline void setValue(int _iValue) { m_ivalue = _iValue; }
protected:int m_ivalue;
};int main(void){
auto_ptr<CTest> pTest(new CTest());pTest->setValue(3);printf("return = %d\n", pTest->getValue());return 0;
}
권장하는 방법.. 하지만 사용이 곤란함,
소유권 독점 방식 Smart Pointer, auto_ptr [C++ 표준]
#include <memory>using namespace std;class CTest{public:
inline int getValue() { return m_ivalue; }inline void setValue(int _iValue) { m_ivalue = _iValue; }
protected:int m_ivalue;
};void modifyTest(auto_ptr<CTest> _pTest){
_pTest->setValue(5);};int main(void){
auto_ptr<CTest> pTest(new CTest());pTest->setValue(3);modifyTest(pTest);printf("return = %d\n", pTest->getValue());return 0;
}
일반적인 포인터의 개념이면빨간색 부분이 추가되어도 됨
결과는 Segmentation error
이유는 Modify ctest가호출되는 시점에 pTest의소유권이 modify ctest로옮겨졌기 때문에 에러남.
소유권 공유 방식, shared_ptr
소유권 공유 방식, shared_ptr
boost::shared_ptr은 C++ 11에서 정식 기능으로 들어오게 되었고,기능은 똑같으니 같이 설명하도록 하겠음.
boost::shared_ptr은 소유권 독점 방식의 auto_ptr 문제를 해결하였고,우리가 알고 있는 공유 개념의 포인터이면서도 메모리는 자동으로 관리되는Smart Pointer
그래서 다음의 코드는 정상적으로 동작함.
소유권 공유 방식, shared_ptr
using namespace std;
class CTest{public:
inline int getValue() { return m_iValue; }inline void setValue(int _iValue) { m_iValue = _iValue; }
protected:int m_iValue;
};
void modifyTest(boost::shared_ptr<CTest> _pTest){
_pTest->setValue(5);};
int main(void){
boost::shared_ptr<CTest> pTest(new CTest());
pTest->setValue(3);
modifyTest(pTest);printf("return = %d\n", pTest-
>getValue());
return 0;}
소스코드
소유권 공유 방식, shared_ptr
shared_ptr은 reference counter를 두어서 해당 shared_ptr을 사용하는객체의 갯수를 관리함.
reference counter의 값이 1이상이라면 이 메모리를 해제하면 안된다로 인식counter가 0보다 클 때는 해당 메모리 영역을 유지하다가 counter가 0이 되면이를 해제함. (즉 shared ptr을 외부적으로 우리가 해제하면 그게 사라진다는 것)
장점
- 편리함
단점
- unnamed shared_ptr 사용 X- 배열 안됨 (사용하기 위해서는 shared_array 사용해야함)- 순환 참조할 시 무한루프- 하나의 객체에 대한 포인터를 두 개 이상의 shared_ptr로 가리키지 말 것
배열에 적용 가능한Smart Pointer shared_array
배열에 적용 가능한 Smart Pointer , shared_array
shared_array는 shared_ptr과는 다르게 new []로 만들어지는 메모리 영역을관리 가능한 smart pointer.
shared_ptr 보다 많이 사용됨
그러므로 소스코드를 보자
배열에 적용 가능한 Smart Pointer , shared_array
[함수 부분]
using namespace std;
class CTest{public:
boost::shared_array<char> allocMemory();};
boost::shared_array<char> CTest::allocMemory() {int iSizeResult = 0;iSizeResult = 50;boost::shared_array<char> pMemoryCreatedInside(new char[iSizeResult]); // 메모리 할당sprintf(pMemoryCreatedInside.get(), "%s", "I am MK!");
// 반환해야 하기 때문에 할당한 메모리를 해제 해서는 안됨return pMemoryCreatedInside;
}
배열에 적용 가능한 Smart Pointer , shared_array
[메인 부분]
int main(void){
boost::shared_ptr<CTest> pTest(new CTest);boost::shared_array<char> pMemoryUsedOutside = pTest->allocMemory();
// allocMemory에서 할당한 값을 사용printf("%s\n", pMemoryUsedOutside.get());
// 일반 포인터였다면 다소 어색하지만 여기서 pMemoryUsedOutside를 해제해야 함return 0;
}
배열에 적용 가능한 Smart Pointer , shared_array
라이브러리 기반으로 개발을 하다보면 메모리의 할당자와 메모리의 참조자, 그리고 메모리의 해제자가 갈라지는 경우에 대한 경우가 많은데이 경우 메모리 해제 문제를 어떻게 처리할 지 고민됨.
shared_array와 shared_ptr은 이 경우에 편리한 점을 제공함.
즉, 포인터에 자유로워 지고 싶다면 Shared 시리즈를 쓰면 됨.
다만 무턱대고 사용하면 안되고 잘 생각하면서 사용해야 한다는 것
shared 시리즈는 멀티 쓰레드 코드에서 안전하게 사용 가능함
C++ 11Unique_ptr
C++ 11 Unique_ptr
새로운 C++ 11의 추가로 C++ 11에 이동 세만틱스가 등장함.
이동 세만틱스은 복사 세만틱스 처럼 두 객체 사이에 복사를 수행하는 대신객체의 데이터 필드 하나 하나를 이동 시키는 역할을 수행함. (이동 세만틱스의 개념은 좀 있다가 볼 예정)
이동 세만틱스이 대두되면서 auto_ptr이 이동 세만틱스를 지원하지 않기 때문에, 처음부터 구축을 하는게 좋다고 생각되면서 Unique_ptr이 만들어짐
하지만 unique_ptr은 내부에 복사 생성자와 할당 연산자가 구현되어 있지 않기때문에 unique_ptr은 move로만 이동 가능함.
C++ 11 Unique_ptr
#1std::unique_ptr<int> p1(new int(5));std::unique_ptr<int> p3 = std::move(p1);p3.reset();p1.reset();
#2std::unique_ptr<Person> p(new Person(1, "baby"));std::cout << "Name: " << p->GetName() << std::endl;std::cout << "Age : " << p->GetAge() << std::endl;
getchar();
다음 장에서만나요 ^^