C++primer 독서노트 9 - 변환 및 클래스 유형

때때로 SmallInt와 같은 특정한 유형의 데이터를 표시하기 위해 자신의 클래스 유형을 지정하면, 계산을 편리하게 하기 위해 변환 조작부호를 지정하여, 이 클래스 유형을 특정한 상황에서 자동으로 지정한 형식으로 변환합니다
<1> 변환 조작부호
operator type();
변환 함수는 클래스 구성원 함수여야 하며, 되돌아오는 형식을 지정할 수 없고, 인삼 목록은 비어 있어야 하며, 변환 대상을 바꿀 수 없기 때문에 조작부호는const 구성원으로 정의됩니다.
#include <iostream>
using namespace std;
class SmallInt
{
public:
	SmallInt(int i=0):val(i)
	{ if(i<0 || i>255) throw std::out_of_range("Bad SmallInt initializer");}
	~SmallInt(void){};
	operator int()const
	{std::cout<<"Translate SmallInt to Int"<<endl;return val;}
private:
	size_t val;
};

<2>2 레벨 전환
SmallInt에서 지정한 변환은 int이지만, SmallInt는 간접적으로 더블,float 등 다른 표준 형식으로 변환할 수 있습니다
SmallInt sm;
double dv;
sm >= dv	//sm convet to int and then convert to double
if(sm)		//sm convet to int and then convert to bool
int x = static_cast<int>(si) + 2;	// instruct compiler SmallInt to int
<3> 전환 금지
가령 Integral 클래스가 하나 더 있다고 가정하면 SmallInt으로 변환할 수 있지만, 2단계 변환이 Integral에서 SmallInt으로 변환된 다음에 int 형식으로 변환할 수 없습니다.
int cal(int);
Integral intVal;
cal(intVal);	//error,no convertion to int from Integral

결론:
SmallInt ->standard type ->standard type	//ok
standard type ->standard type->SmallInt		//ok
Integral->SmallInt->Int				//error
변환 중 하나의 클래스 유형 변환만 사용할 수 있음(클래스 유형 <-> 표준 유형, 클래스 유형 <-> 클래스 유형
<4> 한 클래스에 여러 종류의 변환을 지정하지 마십시오
이렇게 하면 일부 전환할 때의 이의성을 일으킬 수 있다.
class SmallInt
{
public:
	SmallInt(int i=0):val(i){ if(i<0 || i>255) throw std::out_of_range("Bad SmallInt 


initializer");}
	SmallInt(double db):val(db){}
	~SmallInt(void){};
	operator int()const{std::cout<<"Translate SmallInt to Int"<<endl;return val;}
	operator double()const{std::cout<<"Translate SmallInt to double"<<endl;return val;}
private:
	size_t val;
};


void fpComputer(float)
{}
SmallInt sm(100);
fpComputer(sm) 	//error 

<5> 구조 함수 변환 이의성
void manip(const SmallInt&);
double d;
int i;
float f;
mamip(d);	//ok,use SmallInt(double) to convert 
manip(i);	//ok,use SmallInt(int) to convert
manip(f);	//error,ambiguous

<6> 구조 함수 변환과 클래스 유형 변환이 동시에 존재할 때의 이의성
class Integral;
class SmallInt
{
public:
	SmallInt(Integral);
	//...
};
class Intergal
{
public:
	operator SmallInt()const;
	//...
}
void compute(SmallInt);
Integral intVal;
compute(intVal);	//error:ambiguous
여기의Integral 유형의 변수 intVal은 구조 함수와 클래스 유형 변환 두 가지 방식으로 SmallInt로 변환할 수 있기 때문에 이의성을 가진다.
구체적인 해결 방법은 다음과 같이 명시적으로 호출하는 것입니다.
compute(intVal.operator SmallInt());
compute(SmallInt(intVal));

좋은 웹페이지 즐겨찾기