글
연산자 오버로딩
Programming/C++ Language
2009. 9. 30. 18:29
연산자 오버로딩을 할 때는, 연산자 오버로딩 함수가 멤버함수 나 비멤버 함수가 될 수 있다.
멤버 함수 라면, 가장 왼쪽의 피연산자( 혹은 하나뿐인 ) 가 반드시 연산자 클래스의 객체( 또는 개체의 참조 ) 가 되어야 한다.
비멤버 함수 일 경우에는, 왼쪽의 피연산자가 반드시 내장 타입이거나 다른 클래스의 객체가 되어야 한다. 그러나 이 함수가 private 나 protected 멤버에 직접 접근한다면 비멤버함수는 friend 함수로 구현 되어야 한다. 비멤버 함수를 사용하는 다른 이유는, long int 타입과 huge integer 타입 클래스를 더한 다고 했을 때, 이 때 사용할 임시 huge integer 객체를 생성한다. 이 처럼 덧셈 연산자의 피연산항을 교환할 수 있도록 만들 필요가 있다.
get , set 함수가 클래스의 public 인터페이스에 있다면, 비멤버 함수가 반드시 friend가 될 필요는 없다.( 대신, 함수 호출에 따른 부하가 있다 )
ex 1 ) <<, >> 연산자 오버로딩
class PhoneNumber {
friend ostream &operator<<( ostream&, const PhoneNumber &);
friend istream &operator>>( istream&, PhoneNumber & );
}
cin >> phone;
cout << phone << endl;
연산자 오버로딩 정의 및 구현시에 문법은 위와 같다. cin >> phone; 를 컴파일러는 operator >> ( cin, phone ); 와 같은 비멤버 함수 호출을 생성한다. 반환값을 ostream&, istream&로 하는 이유는, 두번째 cout 구문을 보면, 먼저 operator <<( cout, phone ) 을 호출하고 난 뒤에, ostream 이 반환되서 다시 operator << ( cout, endl ) 이 호출되어 << 와 >> 을 연속적으로 사용 가능 하게 해준다.
ex 2 ) 단항 연산자 오버로딩
class String {
friend bool operator!( const String & );
}
class String {
public:
bool operator! () const;
}
( s 는 String 객체 )
멤버 함수가 선언 되어 있을 때는, !s 는 s.operator!(); 호출이 된다.
friend 함수로 선언 되어 있을 때, !s 는 operator!(s) 가 된다.
ex 3 ) 이항 연산자 오버로딩
이항 연산자 오버로딩은 1. 하나의 인수를 갖고, static이 아닌 멤버함수 2. 두 개의 인수( 단, 하나는 반드시 클래스 객체 or 클래스 객체의 참조 )를 갖는 비멤버 함수로 오버로딩 될 수 있다.
1 번 의 경우
public String {
public:
const String &operator+=( const String & );
}
y += z 는 y.operator( z ) 가 된다.
2 번의 경우
class String {
friend const String &operator+=( String &, const String & );
}
y += z 는 operator+=( y, z ) 가 된다.
ex )
const Array& Array::operator=( const Array& right )
{
return *this; // x = y = z; 반복적인 호출 가능하도록
}
int& Array::operator[]( int subscript )
const int& Array::operator[]( int subscript ) const
여기서 위의 [] 연산자는 참조를 반환해서 lvalue 를 생성 하는 것이고,
아래의 [] 연산자는 상수 참조 반환으로 rvalue 를 생성한다. 여기서 주목 할 것은 붉은색 const 이다.
이는 상수 함수를 뜻하는 것으로, 단일 연산자일 경우 a[1] 라고 코딩 했을때 이는 a.operator[]( 1 ) 이 될 것인데 여기서 a 는 상수 이기 때문에 상수 함수로 취할 필요가 있다. 물론 이항 연산자일 경우에는 필요 없을 것이다.
멤버 함수 라면, 가장 왼쪽의 피연산자( 혹은 하나뿐인 ) 가 반드시 연산자 클래스의 객체( 또는 개체의 참조 ) 가 되어야 한다.
비멤버 함수 일 경우에는, 왼쪽의 피연산자가 반드시 내장 타입이거나 다른 클래스의 객체가 되어야 한다. 그러나 이 함수가 private 나 protected 멤버에 직접 접근한다면 비멤버함수는 friend 함수로 구현 되어야 한다. 비멤버 함수를 사용하는 다른 이유는, long int 타입과 huge integer 타입 클래스를 더한 다고 했을 때, 이 때 사용할 임시 huge integer 객체를 생성한다. 이 처럼 덧셈 연산자의 피연산항을 교환할 수 있도록 만들 필요가 있다.
get , set 함수가 클래스의 public 인터페이스에 있다면, 비멤버 함수가 반드시 friend가 될 필요는 없다.( 대신, 함수 호출에 따른 부하가 있다 )
const test operator + ( const test& ) const;
const test : 리턴 타입
opertor + : 함수이름
const test& : 인수 = 피연산자
const : 상수 함수
const test : 리턴 타입
opertor + : 함수이름
const test& : 인수 = 피연산자
const : 상수 함수
ex 1 ) <<, >> 연산자 오버로딩
class PhoneNumber {
friend ostream &operator<<( ostream&, const PhoneNumber &);
friend istream &operator>>( istream&, PhoneNumber & );
}
cin >> phone;
cout << phone << endl;
연산자 오버로딩 정의 및 구현시에 문법은 위와 같다. cin >> phone; 를 컴파일러는 operator >> ( cin, phone ); 와 같은 비멤버 함수 호출을 생성한다. 반환값을 ostream&, istream&로 하는 이유는, 두번째 cout 구문을 보면, 먼저 operator <<( cout, phone ) 을 호출하고 난 뒤에, ostream 이 반환되서 다시 operator << ( cout, endl ) 이 호출되어 << 와 >> 을 연속적으로 사용 가능 하게 해준다.
ex 2 ) 단항 연산자 오버로딩
class String {
friend bool operator!( const String & );
}
class String {
public:
bool operator! () const;
}
( s 는 String 객체 )
멤버 함수가 선언 되어 있을 때는, !s 는 s.operator!(); 호출이 된다.
friend 함수로 선언 되어 있을 때, !s 는 operator!(s) 가 된다.
ex 3 ) 이항 연산자 오버로딩
이항 연산자 오버로딩은 1. 하나의 인수를 갖고, static이 아닌 멤버함수 2. 두 개의 인수( 단, 하나는 반드시 클래스 객체 or 클래스 객체의 참조 )를 갖는 비멤버 함수로 오버로딩 될 수 있다.
1 번 의 경우
public String {
public:
const String &operator+=( const String & );
}
y += z 는 y.operator( z ) 가 된다.
2 번의 경우
class String {
friend const String &operator+=( String &, const String & );
}
y += z 는 operator+=( y, z ) 가 된다.
ex )
const Array& Array::operator=( const Array& right )
{
return *this; // x = y = z; 반복적인 호출 가능하도록
}
int& Array::operator[]( int subscript )
const int& Array::operator[]( int subscript ) const
여기서 위의 [] 연산자는 참조를 반환해서 lvalue 를 생성 하는 것이고,
아래의 [] 연산자는 상수 참조 반환으로 rvalue 를 생성한다. 여기서 주목 할 것은 붉은색 const 이다.
이는 상수 함수를 뜻하는 것으로, 단일 연산자일 경우 a[1] 라고 코딩 했을때 이는 a.operator[]( 1 ) 이 될 것인데 여기서 a 는 상수 이기 때문에 상수 함수로 취할 필요가 있다. 물론 이항 연산자일 경우에는 필요 없을 것이다.
'Programming > C++ Language' 카테고리의 다른 글
static 클래스 멤버 (0) | 2010.03.19 |
---|---|
namespace (0) | 2010.03.19 |
순수 가상 함수 (0) | 2009.09.26 |
가상 함수의 활용 (0) | 2009.09.25 |
가상 함수에 대한 이해 (0) | 2009.09.25 |