'explicit'에 해당되는 글 2건

  1. 2009.10.07 사용자 정의 타입변환 함수에 대한 주의를 놓지 말자.
  2. 2009.04.30 explicit
[ Programming ]2009. 10. 7. 20:34

컴파일러가 사용할 수 있는 타입변환 함수는 2가지.

1.     단일 인자 생성자.
:
이런 생성자는 매개변수가 하나를 받도록 선언 되어 있든지, 매개변수가 여러 개인데 처음 것을 제외한 나머지가 모두 기본값을 갖도록 선언 되어 있는 것.
두가지 방법이 있음.
explicit 키워드를 사용.
두 번의 사용자 정의 변환.

// Test.cpp : 콘솔 응용 프로그램에 대한 진입점을 정의합니다.
//

#include "stdafx.h"


template< class T >
class Array
{
public:
	/// 클래스 내부에 클래스를 넣어서 Array에서만 사용한다는것을 강조.
	/// public에 선언 해서 다른 사람들도 사용할 수 있도록...
	class ArraySize
	{
	public:
		ArraySize(int numElements)
			: theSize(numElements)
		{

		}
		int size() const
		{
			return theSize;
		}
	private:
		int theSize;
	};

	Array(int lowbound, int highBound)
	{

	}
	/// 단일 인자를 int 대신 ArraySize로 받음.
	Array(ArraySize _size)
		:m_ArraySize(_size)
	{
	}
	T& operator [] (int index)
	{

	}
	friend bool operator== (const Array< int >& lhs, const Array< int >& rhs);
private:
	ArraySize m_ArraySize;
};

bool operator== (const Array< int >& lhs, const Array< int >& rhs)
{
	/// 비교후 리턴.
	return true;
}

int _tmain(int argc, _TCHAR* argv[])
{
	/// int 10을 ArraySize _size에 있는 단일 인자를 사용하여
	/// 임시 _size에 넣고 임시 _size로 m_ArraySize를 초기화. 
	Array< int > a(10);

	/// 이렇게 두번의 사용자 정의 변환을 하게 해서
	/// 컴파일 에러가 나게 해서 오작동을 예방 할 수 있음.

	/// 모어 이펙티브 C++ 항목5.
	return 0;
}


2.     암시적 타입변환 연산자
:
변환 함수 => 객체에서 하나의 수로 변환 할 때.
ex> operator double() const;
생성자를 사용하지 않음. 변환 함수를 이용.
변환 함수는 클래스의 메소드 여야 한다.
변환 함수는 리턴형을 가지면 안 된다.
변환 함수는 전달인자를 가지면 안 된다.
암시적 타입변환 연산자를 사용되면 프로그래머가 의도하지 않은 결과를 초래 할 수 있는데 이를 방지 하기 위해서 타입변환 함수를 직업 정의하고 호출하는 방법으로 하면 된다.

// test2.cpp : 콘솔 응용 프로그램에 대한 진입점을 정의합니다.
//

#include "stdafx.h"
#include < iostream >
using namespace std;

class Rational
{
public:
	Rational(const int _iFint, const int _iSint)
		:m_iFint(_iFint), m_iSint(_iSint)
	{

	}
// 	/// 변환 함수가 있을 경우.
// 	/// 변환 함수.
// 	operator double() const
// 	{
 		return static_cast< double >( static_cast< double >(m_iFint) / static_cast< double >(m_iSint) );
// 	}

	/// 변환 함수가 없을 경우.
	/// 변환 함수를 사용하지 않고 함수를 직접 만듬.
	double asDouble() const
	{
		return static_cast< double >( static_cast< double >(m_iFint) / static_cast< double >(m_iSint) );
	}
private:
	int m_iFint;
	int m_iSint;
};

int _tmain(int argc, _TCHAR* argv[])
{
	Rational test(1, 2);

	/// 변환 함수가 있을 경우.
	/// operator <<를 작성 하지 않았는데 
	/// 암시적 타입변환으로 에러를 발생하지 않는다. 
	/// 즉, 프로그래머가 의도하지 않은 결과를 만들 수 있음.
//	cout << "operator double() const : " << test << endl;

	/// 변환 함수를 없을 경우,
	/// 에러 발생. operator double() const가 있을 경우 됨.
	cout <<  "operator double() const : " << test << endl;
	/// 함수를 직접 호출로 의도 하지 않았던 잘못된 호출을 막을 수 있음.
	cout <<  "double asDouble() const : "  << test.asDouble() << endl;		

	

	return 0;
}
Posted by 냉동
[ Programming ]2009. 4. 30. 01:07
표준 데이터형의 어떤 값을 다른 표준 데이터형의 한 변수에 대입하는 명령문을 작성하면, C++는 그 값의 데이터형을, 대입받는 입장에 있는 변수와 동일한 데이터형으로 자동으로 변환하여, 두 데이터 형이 서로 호환이 되게 만든다. 단, C++는 호환되지 않는 데이터형은 자동으로 변환하지 않는다. 예를 들면,  int *p = 10; // 데이터형이 불일치라서 컴파일 에러를 나타낸다. 강제 데이터형 변환을 하면 컴파일 에러를 넘길수 있다. int *p = (int*)10; 이렇게 자동변환을 할것인지 강제 변환을 할것인지를 사용자가 정할 수 있다.
// test.cpp : 콘솔 응용 프로그램에 대한 진입점을 정의합니다.
//

#include "stdafx.h"

class CTest
{
public:
	CTest() : m_i(0)
	{

	}
	/// C++에서, 하나의 전달이자를 취하는 생성자는 
	/// 그 전달인자 데이터형의 값을 클래스형으로 변환하는 설계도처럼 동작.
	/// 다음의 생성자는 int형 값을 CTest형 값으로 변환하는 명령문 역활.
	/// 주의 : 하나의 전달인자만 사용할 수 있는 생성자만이 이와 같은 변환 함수로 동작.
	/// explicit는 아래 설명.
	/*explicit*/ CTest(int i) : m_i(i)	/// int을 CTest 객체로 변환하는 템플릿.
	{

	}
	~CTest()
	{

	}
	void Print() const
	{
		std::cout << "m_i의 값 : " << m_i << std::endl;
	}
private:
	int m_i;
};

int _tmain(int argc, _TCHAR* argv[])
{
	/// CTest(int i)을 사용하여 10을 CTest로 변환.
	/// CTest(int i) 생성자를 사용하여, CTest 임시 객체를 생성한다.
	/// 이때 10으로 초기화 한다. 그리고 나서 멤버별 대입으로 임시 객체의 내용을
	/// Test에 복사한다. 이런 자동으로 이루어지는 형변환을 암시적 데이터형 변환이라 한다.
	/// explicit 주석시 암시적 형 변환.
	/// explicit 주석 없을시 컴파일 에러.
	/// error C2440: '초기화 중' : 'int'에서 'CTest'(으)로 변환할 수 없습니다.
	CTest Test = 10;

	Test.Print();

	/// explicit 주석 없을시 명시적 형 변환.
	Test = CTest(11);
	Test.Print();
	Test = (CTest)12;
	Test.Print();
	
	return 0;
}
/// 이런 자동적인 데이터 형 변환으로 인해 편할수도 있지만, 오히려 독이 될수도 있다.
/// 그래서 최신 C++ 시스템에는 자동 데이터형 변환을 못하게 하는 explicit라는 새로운 키워드가
/// 추가 되었다.
Posted by 냉동