내용이 기존 문법과 함께 여기저기 흩어져 있어 보기에 좀 어려워
MSDN을 참고하여 대충 정리하려함.
역시 설명은 MSDN이 갑이다..
C++11/14/17 기능에 대한 지원(최신 C++)
: https://msdn.microsoft.com/ko-kr/library/hh567368.aspx
C++ 형식 시스템
: https://msdn.microsoft.com/ko-kr/library/hh279663.aspx이제 auto를 사용하자.
값형식
: https://msdn.microsoft.com/ko-kr/library/hh438479.aspxValue vs. reference types
* copy by value, copy by reference에 대한 개념 때문인지 내용이 어색 하기는 함.
- 본문에서 C++ class는 value type이지만 객체지향(OOP)를 지원하고 다형성 동작을 가능하도록 reference type으로 지정할 수도 있음.
- Value type은 메모리, 레이아웃 제어와 관련이 있고 reference type은 다형성을 위한 base class와 가상함수(virtual functions)와 관련이 있음.
- Value type은 copyable (복사생성자-copy constructor, 복사연산자copy assignment operator 활성화)하지만 Reference type은 non-copyable(복사생성자, 복사연산자 비활성화)하고 다형성을 지원하는 가상 소멸자(virtual destructor)를 사용함.
- Value type은 위의 특성 상 복사가능하고 각기 독립적인 값을 제공하는 contents 용도로 주로 사용되고 reference type은 다형성의 측면에서 object의 identity를 나타내며 polymorphic type이라고도 불린다. (??)
아래는 reference type의 예
class MyRefType { private: MyRefType & operator=(const MyRefType &); MyRefType(const MyRefType &); public: MyRefType () {} }; int main() { MyRefType Data1, Data2; // ... Data1 = Data2; }
: 복사생성자와 복사연산자를 private로 지정하여 복사할 수 없게 만들었음.
Value types and move efficiency
새로운 복사 최적화로 인해 복사 할당 오버헤드가 방지됨.
컴파일러의 copy allocation overhead 방지를 위해 이동 생성자를 생성 될 수 있는데 적절한 이동을 위해서는 사용자가 직접 &&를 사용하여 이동 생성자와 이동 연산자를 정의해야 한다.
복사 생성자를 사용할 필요가 있다면 이동 생성자를 정의하는 것이 deep copy보다 효율적임. 또한 이동을 고려하되 복사를 방지하고자 할 경우 unique_ptr를 사용하는 것도 방법임.
이동 문법은 함수에서 값을 리턴하거나 container에 삽입하는 상황에서 사용 될 수 있어 복사보다 효율적임.
#include <set> #include <vector> #include <string> using namespace std; //... set<widget> LoadHugeData() { set<widget> ret; // ... load data from disk and populate ret return ret; } //... widgets = LoadHugeData(); // efficient, no deep copy vector<string> v = IfIHadAMillionStrings(); v.insert( begin(v)+v.size()/2, "scott" ); // efficient, no deep copy-shuffle v.insert( begin(v)+v.size()/2, "Andrei" ); // (just 1M ptr/len assignments) //... HugeMatrix operator+(const HugeMatrix& , const HugeMatrix& ); HugeMatrix operator+(const HugeMatrix& , HugeMatrix&&); HugeMatrix operator+( HugeMatrix&&, const HugeMatrix& ); HugeMatrix operator+( HugeMatrix&&, HugeMatrix&&); //... hm5 = hm1+hm2+hm3+hm4+hm5; // efficient, no extra copies
value-like class에서도 deep copy 보다 move를 사용하는 것이 효율적일 수 있고 이동 생성자, 이동 연산자를 생성하여 적절히 이동 될 수 있도록 할 수 있다.
#include <memory> #include <stdexcept> using namespace std; // ... class my_class { unique_ptr<BigHugeData> data; public: my_class( my_class&& other ) // move construction : data( move( other.data ) ) { } my_class& operator=( my_class&& other ) // move assignment { data = move( other.data ); return *this; } // ... void method() { // check (if appropriate) if( !data ) throw std::runtime_error("RUNTIME ERROR: Insufficient resources!"); } };
형식 변환 및 형식 안정성
: https://msdn.microsoft.com/ko-kr/library/hh279667.aspx
암시적 형식 변환(Implicit conversion)
당연하겠지만 확대 변환은 데이터의 손실, 축소 변환은 데이터 손실 발생 가능.
명시적 변환(Explicit conversion, casts)
아래는 C 스타일 캐스트 연산자임.
(int) x; // old-style cast, old-style syntax int(x); // old-style cast, functional syntax
static_cast : 컴파일 시점에서 문제 없을 경우 캐스팅
double d = 1.58947; int i = d; // warning C4244 possible loss of data int j = static_cast<int>(d); // No warning. string s = static_cast<string>(d); // Error C2440:cannot convert from // double to std:string // No error but not necessarily safe. Base* b = new Base(); Derived* d2 = static_cast<Derived*>(b);
dynamic_cast : 런타임시 기본 타입에서 파생 타입으로 캐스팅, 일부 오버헤드 있음.
Base* b = new Base(); // Run-time check to determine whether b is actually a Derived* Derived* d3 = dynamic_cast<Derived*>(b); // If b was originally a Derived*, then d3 is a valid pointer. if(d3) { // Safe to call Derived method. cout << d3->DoSomethingMore() << endl; } else { // Run-time check failed. cout << "d3 is null" << endl; } //Output: d3 is null;
const_cast : const<->비const로 캐스팅, 근데 사용하는 건 좀..
void Func(double& d) { ... } void ConstCast() { const double pi = 3.14; Func(const_cast<double&>(pi)); //No error. }
reinterpret_cast : 그냥 캐스팅
아래는 관련 캐스팅의 차이
const char* str = "hello"; int i = static_cast<int>(str);//error C2440: 'static_cast' : cannot // convert from 'const char *' to 'int' int j = (int)str; // C-style cast. Did the programmer really intend // to do this? int k = reinterpret_cast<int>(str);// Programming intent is clear. // However, it is not 64-bit safe.
댓글 없음:
댓글 쓰기