Notice
Recent Posts
Recent Comments
Link
- 책_곽용재님 홈페이지
- 책_노란북 - 책 가격비교
- 책_김재우-SICP번역
- 플밍_쏘쓰포지
- 플밍_CodingHorror ?
- 플밍_상킴
- 플밍_김민장님
- GPGStudy
- 플밍_미친감자님
- 플밍_jz
- 플밍_샤방샤방님
- 플밍_글쓰는프로그래머2
- 플밍_키보드후킹
- 사람_재혁
- 사람_kernel0
- 사람_박PD
- 사람_경석형
- 사람_nemo
- 사람_kikiwaka
- 사람_Junios
- 사람_harry
- 사람_어떤 개발자의 금서목록..
- 사람_모기소리
- 사람_낙타한마리
- 사람_redkuma
- 사람_영원의끝
- 사람_민식형
- 도스박스 다음카페
- 플레이웨어즈 - 게임하드웨어벤치마크
- http://puwazaza.com/
- David harvey의 Reading Marx's c…
- 씨네21
- 한겨레_임경선의 이기적인 상담실
- 본격2차대전만화 - 굽시니스트
- 영화_정성일 글모음 페이지
- 영화_영화속이데올로기파악하기
- 음식_생선회
- 죽력고
- 사람_한밀
- 플밍_수까락
일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | 3 | 4 | |||
5 | 6 | 7 | 8 | 9 | 10 | 11 |
12 | 13 | 14 | 15 | 16 | 17 | 18 |
19 | 20 | 21 | 22 | 23 | 24 | 25 |
26 | 27 | 28 | 29 | 30 | 31 |
Tags
- 일리아스
- template
- 진중권
- 게임
- 정성일
- 영화
- 강유원
- 유시민
- modernc++
- stl
- 소비자고발
- Programming
- 진삼국무쌍5
- 노무현
- programming challenges
- 태그가 아깝다
- 고전강의
- BSP
- 삼국지6
- 프로그래밍
- 김두식
- 단상
- 고등학교 사회공부
- 책
- 삼국지
- 인문학
- 정신분석
- c++
- 건강
- 유머
Archives
- Today
- Total
01-05 01:43
lancelot.com
conversion 본문
- 변환연산자 : 객체가 다른 타입으로 변환될 때 호출되는 함수
- 함수이름에 반환이 있기때문에 반환 타입을 표기하지 않는다
operator TYPE() const // 상수 멤버함수로 만드는 경우가 많다
{
return 값;
}
- 변환 연산자 vs 변환 생성자
- int pn, Int32 un 일때
- pn=un; ==>: un.operator int();
- 변환연산자
- 객체(Int32) => Int로 변환될 때
- un=pn; ==> pn.opertor Int32() 는 만들 수 없다.
- 대입연산자, un.operator=(int) 가 가능한지 찾아보고
- 변환생성자, Int32(pn) 이 가능한지 찾는다.
- pn=un; ==>: un.operator int();
- int pn, Int32 un 일때
#include<iostream>
class Int32
{
int value;
public :
Int32() : value(0) {}
Int32(int val) : value(val) { } // 변환생성자
// 변환 연산자 : 객체가 다른 타입으로 변환될 때 호출되는 함수
// operator TYPE()
// {
// return 값
// }
// -> 반환타입을 표기하지 않는다. 함수이름에 이미 포함되어있기때문.
operator int() const
{
return value;
}
void operator=(int val)
{
value = val;
}
};
int main()
{
int pn;
Int32 un;
pn = un;// un.operator int()
un = pn;// pn.operator int32() 는 만들 수 없다
// 1. un.operator=(pn) 이 가능한지 찾고
// 2. Int32(pn) 이 가능한지 찾는다
}
- 변환생성자(인자가 한 개인 생성자)가 있다면
Int32 n1(3); // direct initialization
Int32 n2=3; // copy initialization
Int32 n3{3}; // direct initialization : C++11
Int32 n4={3} // copy initialization : C++11
n1=3; // conversion (int -> Int32)
- Int32 n2 = 3; ==> Int32 n2 = int32(3);
- C++14까지
- 인자가 한 개인 생성자를 사용해서 "Int32 임시객체 생성"
- 생성된 임시객체를 "복사생성자(C++98)" 또는 "move 생성자(C++11이후)" 를 사용해서 n2에 복사(이동)
- 대부분의 컴파일러가 최적화를 통해 "임시객체 생성이 제거"됨.
- C++17 이후
- 임시객체를 생성하지 않고, 인자 한 개인 생성자 호출 ( 복사생성자를 사용하지 않음)
- C++14까지
#include<iostream>
class Int32
{
int value;
public :
Int32(int n) : value(n) {}
Int32(const Int32&) = delete;// VS2022 에서는 /Std:C++14 해도 잘됨 -_-;
Int32& operator=(const Int32&) = delete;
};
int main()
{
Int32 n1(3);
Int32 n2 = 3;
Int32 n3{ 3 };
Int32 n4 = { 3 };
n1 = 3;
}
- n1=3; ==> n1=Int32(3);
- 인자가 한 개인 생성자를 사용해서 Int32 임시객체 생성
- 생성된 임시객체를 디폴트 대입 연산자를 사용해서 n1에 대입
- 대부분 컴파일러가 "최적화를 통해 임시객체 생성이 제거"됨.
- 디폴트 대입연산자가 삭제된 경우 "컴파일 에러" 발생
- explicit 생성자
- 생성자가 암시적 변환의 용도로 사용될 수 없게 한다.
- 직접 초기화 ( direct initialization ) 만 가능하고 복사 초기화 ( copy initialization ) 도 사용할 수 없다.
class Vector
{
public :
// explicit 생성자
// -> 생성자가 암시적 변환의 용도로 사용될 수 없게한다
// 직접 초기화 ( direct initialization ) 만 가능하고 복사 초기화 ( copy initialization ) 도 사용할 수 없다.
explicit Vector(int size) {}
};
void foo(Vector v) {}
int main()
{
Vector v1(3);
Vector v2 = 3; // error
Vector v3{ 3 };
Vector v4 = { 3 }; // error
v1 = 3; // error
foo(3); // error
}
- explicit 변환 연산자
- 객체의 유효성을 if 문으로 조사하고 싶다
- operator bool() 을 제공하면 된다
- operator bool() 은 side effect 가 많다
- explicit operator bool()
- C++11 부터 생성자 뿐 아니라 "변환 연산자도 explicit 를 붙일 수 있다"
- bool 로의 암시적 변환은 허용되지 않음
- if문안에서는 사용가능
- "safe bool"
- 객체의 유효성을 if 문으로 조사하고 싶다
- C++ 버전과 explicit
- explicit 변환 생성자 : C++98
- explicit 변환 연산자 : C++11
- explicit(bool) : C++20
class Machine
{
int data = 10;
bool state = true;
public :
explicit operator bool() { return state; }
};
int main()
{
Machine m;
bool b1 = m; // error
bool b2 = static_cast<bool>(m);
m << 10; // error
if (m)
{
}
}
- explicit(bool) : C++20
- 조건에 따라 explicit의 여부를 결정함
#include<iostream>
#include<type_traits>
template<class T>
class Number
{
T value;
public :
// C++20 부터 가능 - explicit(bool)
explicit(!std::is_integral_v<T>) Number(T v) : value(v){}
};
int main()
{
// C++17 부터 template의 타입 생략 가능
Number n1 = 10; // ok
Number n2 = 3.4;// error
}
- nullptr
- null pointer를 의미
- 포인터 초기화시 0을 사용하지 말고 nullptr을 사용해라.
- boost 라이브러리에 있는 도구를 C++11을 만들면서 표준에 추가한 것 ( 현재는 C++ keyword )
- nullptr 의 타입
- std::nullptr_t
void foo(int* p) {}
void goo(char* p) {}
struct nullptr_t
{
template<typename T>
constexpr operator T* () const { return 0; }
};
nullptr_t xnullptr;
int main()
{
foo(xnullptr);
goo(xnullptr);
}
- return type resolver - 좌변을 보고 우변의 반환 타입을 자동으로 결정하는 테크닉
#include<iostream>
template<typename T>
T* Allocation(std::size_t sz)
{
return new T[sz];
}
// 위의 Allocation 의 경우는 type을 생략할 수 없다.
// 타입을 생략하려면? - return type resolver
struct Alloc
{
std::size_t size;
public:
Alloc(std::size_t sz) : size(sz) {}
template<typename T>
operator T*() { return new T[size]; }
};
int main()
{
int* p1 = Allocation<int>(10);
double* p2 = Allocation<double>(10);
int* p3 = Alloc(10); // 임시객체.operator int*()
double* p4 = Alloc(10);
}
- 람다표현식과 변환
int main()
{
auto f1 = [](int a, int b) { return a + b; };// 보통은 이렇게 auto 변수에 대입
// 함수포인터에도 대입가능
// -> 람다 표현식 부분에 임시객체가 생성
// -> 임시객체.operator 함수포인터() 함수가 불리는 것
// -> 컴파일러가 생성하는 임시객체에는 operator 함수포인터() 가 자동으로 만들어짐
int(*f2)(int, int) = [](int a, int b) { return a + b; };
}