자바 Wrapper Class




안녕하세요 열코입니다.

이번 시간에는 자바의 래퍼(Wrapper) 클래스에 대해 알아보도록 하겠습니다.


☞ 래퍼 클래스란


래퍼(Wrapper) 클래스는 기본 자료형(Data Type)을 래핑하거나 포함하는 클래스입니다.

여기서 기본 자료형은 int, char, long, float, double..등을 말합니다.

래퍼 클래스에 객체를 만들면 필드가 포함되며 이 필드에는 기본 자료형을 저장할 수 있습니다.



래퍼 클래스 사용


1. 기본 자료형을 객체로 변환합니다. 메소드에 전달된 인수를 수정하려면 객체가 필요합니다.

- 기본 자료형의 전달은 값의 전달이기 때문

2. java.util 패키지 클래스는 객체만 처리하기 때문에 래퍼 클래스가 필요합니다.

3. 어레이리스트또는 벡터와 같은 Collection 프레임워크의 데이터 구조에는 기본 유형이 아닌 객체 유형만 저장됩니다.

4. 멀티 쓰레딩에서 동기화를 지원하려면 객체가 필요합니다.



기본 데이터 타입 및 해당 래퍼 클래스


기본 데이터 타입 

래퍼 클래스

char

Character

byte

Byte

short

Short

int(long)

Integer

 float

Float

double

Double

boolean

Boolean



오토 박싱 / 언박싱


기본 자료형을 해당 래퍼 클래스의 객체로 자동 변환하는것을 오토 박싱(AutoBoxing)이라고 합니다.



1
2
3
4
5
6
7
8
9
10
11
12
import java.util.ArrayList; 
class Autoboxing 
    public static void main(String[] args) 
    { 
        char ch = 'c'
        Character a = ch; // 오토박싱
  
        ArrayList<Integer> arrayList = new ArrayList<Integer>(); 
        arrayList.add(5); // 오토박싱
    } 
cs


언박싱은 오토박싱의 역과정입니다. 래퍼 클래스의 객체를 해당 기본 자료형으로 변환하는것을 언박싱(Unboxing)이라고 합니다.



1
2
3
4
5
6
7
8
9
10
11
12
13
import java.util.ArrayList; 
class Unboxing 
    public static void main(String[] args) 
    { 
        Character ch = 'c'
        char a = ch; // 언박싱
  
        ArrayList<Integer> arrayList = new ArrayList<Integer>(); 
        arrayList.add(5); 
        int num = arrayList.get(0);  // 언박싱
    } 
cs



예제코드


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
class WrappingUnwrapping 
    public static void main(String args[]) 
    { 
        byte a = 1
        Byte byteobj = new Byte(a); // byte -> Byte 객체 래핑
        int b = 10
        Integer intobj = new Integer(b); // int -> Integer 객체 래핑
        float c = 18.6f; 
        Float floatobj = new Float(c); // float -> Float 객체 래핑
        double d = 250.5
        Double doubleobj = new Double(d); // double-> Double 객체 래핑
        char e='a'
        Character charobj=e; // char -> Character 객체 래핑
 
  
        byte bv = byteobj; // Byte 객체 -> byte 언래핑
        int iv = intobj; // Integer 객체 -> int 언래핑
        float fv = floatobj; // Float 객체 -> float 언래핑
        double dv = doubleobj; // Double 객체 -> double 언래핑 
        char cv = charobj; // Character 객체 -> char 언래핑
    } 
cs



이상 'Java Wrapper Class'에 대해 알아보았습니다.

질문 또는 오타나 잘못된 정보가 있는 경우 댓글로 달아주세요!

공감♡ 버튼을 눌러주시면 더욱 유용하고 좋은 포스팅으로 찾아 뵙겠습니다.




C++ 연산자 오버로딩




안녕하세요 열코입니다.

저번시간에 함수 오버로딩에 대해 알아보았는데요.

이번시간에는 연산자 오버로딩에 대해 알아보도록 하겠습니다.


☞ 연산자 오버로딩이란

기존의 제공하고 있는 연산자를 재정의하여 사용자 정의 클래스로 사용하는 것을 말합니다.

대부분의 기본 제공 연산자 함수는 전역 함수 또는 클래스로 재정의 가능합니다.

오버로드 된 연산자는 함수로 구현됩니다.



☞ 연산자 오버로드에 대한 일반 규칙

  • **과 같은 새로운 연산자를 정의할 수는 없습니다.

  • 기본 제공 데이터 형식에 적용할 때 연산자의 의미를 다시 정의 할 수 없습니다.

  • 오버로드 된 연산자는 비정적(non-static) 클래스 멤버 함수거나 전역 함수이어야 합니다.

   (private 또는 protected 접근자의 전역 함수는 해당 클래스의 friend로 선언해야 합니다.)
  • 단항 연산자 또는 이항 연산자(&, *, +, -)로 오버로드 가능하며 각 사용을 별도로 오버로드 할 수 있습니다.

  • 멤버 함수로 오버로드된 연산자의 첫번째 파라미터는 항상 연산자가 호출되는 객체의 클래스 형식입니다.

   (첫번째 파라미터에 대한 변환은 제공되지 않습니다.)




 오버로딩 불가능한 연산자

아래 표의 연산자들은 오버로드 할 수 없습니다.


 연산자

이름 

멤버선택 

.* 

멤버 포인터 선택 

:: 

범위 

?: 

조건 

문자열 전처리기 변환 

## 

전처리기 연결 



 간단한 예


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
#include <iostream>
using namespace std;
 
class Point {
private :
    int x, y;
 
public :
    Point(int x_, int y_) {
        x = x_;
        y = y_;
    }
 
    void print() {
        cout << "x : " << x << ", y : " << y << "\n";
    }
};
 
 
int main(void) {
    Point p1 = { 11 };
    Point p2(22);
    
    Point p3 = p1 + p2;
 
    p3.print();
 
    return 0;
}
cs

다음과 같이 Point라는 클래스가 있고 Point 클래스 내부에는 int x와 int y가 있습니다.
main함수에서 Point 객체인 p1과 p2를 생성해주고, p3에는 p1과 p2를 더한값을 저장하고 싶습니다.
근데 + 연산자에 대해 Point 객체의 덧셈은 지원 해주지 않습니다.
Point 클래스는 방금 제가 임의로 만든 클래스이며, + 연산자가 무엇을 의미하는지 모르기 때문이죠.
마치 String 변수의 + 연산이 a+a = aa인지 a+a=b인지 모르는것 처럼요.


이를 해결하기 위해 C++에서는 연산자 오버로딩을 제공합니다.
설명은 위에서 해드렸으니 코드에 대해 설명하겠습니다.
먼저 Point 클래스의 + 연산자에 대한 오버로딩 예제 코드입니다.

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
32
33
34
35
#include <iostream>
using namespace std;
 
class Point {
private :
    int x, y;
 
public :
    Point(int x_, int y_) {
        x = x_;
        y = y_;
    }
 
    void print() {
        cout << "x : " << x << ", y : " << y << "\n";
    }
 
    Point operator + (Point& p) {
        x = x + p.x;
        y = y + p.y;
        return Point(x, y);
    }
};
 
 
int main(void) {
    Point p1 = { 11 };
    Point p2(22);
    
    Point p3 = p1 + p2;
 
    p3.print();
 
    return 0;
}
cs

18번째 줄을 보시면 새로운 함수가 하나 생성되었습니다.
+ 연산자에 대한 오버로딩 함수인데요. 하나씩 살펴보겠습니다. ^^
반환형으로는 Point 객체네요. 
함수의 이름은 operator입니다. 함수의 이름을 operator로 사용함으로써 컴파일러에게 연산자 오버로드 함수인것을 명시합니다.
뒤에 연산자 +를 입력했습니다. 매개변수로는 Point 객체의 참조변수입니다.

30번째 줄을 보시면 Point p3 = p1 + p2; 라는 코드가 있습니다.
여기서 p1이 오버로드 된 + 연산자 함수를 호출했으며, + 뒤에있는 p2는 Point& p로 넘겨 받아지는 것 입니다.
반환값은 Point 객체로 x와 y가 각각 더해진 새로운 임시 Point 객체를 반환합니다.
이 반환된 임시 객체 값이 p3 값으로 넘어가서 결과적으로 3, 3이 출력되는 것입니다.

ㅇ 출력 결과

x : 3, y : 3


☞ 연산자 오버로딩 활용 1
데이터 타입 변환에 대한 연산자 또한 오버로딩 할 수 있습니다.
다음 예제를 확인해보세요.

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
#include <iostream>
using namespace std;
 
class DIV {
private :
    int num, div;
public :
    DIV(int n, int d) {
        num = n;
        div = d;
    }
 
    operator double() const {
        return double(num) / double(div);
    }
};
 
 
int main(void) {
    DIV d(13);
    double db = d;
    cout << d;
 
    return 0;
}
cs

21번째 줄을 보시면 double 변수로 db를 선언하고 값을 DIV 객체인 d를 넘겨주었습니다.
어떻게 이게 가능할까요?
13번째 줄을 보시면 double 이라는 키워드를 연산자 오버로딩하여 double 값을 반환하는 함수로 오버로딩 했습니다.
그러므로 double 변수에 대입할 수 있게 된 것이죠.

☞ 연산자 오버로딩 활용 2
cin, cout의 << 연산자, >> 연산자 오버로딩 역시 가능합니다.
다음 예제 코드는 cin 의 << 연산자에 대한 오버로딩 입니다.

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
#include <iostream>
using namespace std;
 
class Point {
private :
    int x, y;
 
public :
    Point(int x_, int y_) {
        x = x_;
        y = y_;
    }
 
    friend ostream& operator<<(ostream&const Point&);
};
 
ostream& operator<<(ostream& os, const Point& p) {
    os << p.x << ", " << p.y;
    return os;
}
 
int main(void) {
    Point p(23);
    
    cout << p;
 
    return 0;
}
cs

Point라는 클래스가 있습니다. p 라는 객체를 생성하고 cout << p; 라는 코드는 분명 오류가 발생합니다.
왜나면 cout의 << 연산자는 기본적으로 사용자 정의 클래스에 대한 출력을 지원해 주지 않기 때문이죠.
이를 연산자 오버로딩을 통해 해결 가능합니다.
17번째 줄을 보시면 << 연산자에 대한 오버로드 함수입니다.
또한 Point 객체의 private 멤버인 x와 y에 접근 할 수 있도록 Point 클래스 내부에 friend 함수를 지정해 주었습니다.

ㅇ 출력 결과

2, 3



이상 '연산자 오버로딩'에 대해 알아보았습니다.

질문 또는 오타나 잘못된 정보가 있는 경우 댓글로 달아주세요!

공감♡ 버튼을 눌러주시면 더욱 유용하고 좋은 포스팅으로 찾아 뵙겠습니다.



'C, C++' 카테고리의 다른 글

C 변수 선언 및 키워드  (0) 2018.10.25
C 표준 입력 함수 scanf  (0) 2018.10.23
C 표준 출력 함수 printf()  (0) 2018.10.22
C++ 가상 함수(Virtual Function)  (8) 2018.10.19
C++ 함수 오버로딩  (0) 2018.10.11
C/C++ 메모리 동적할당  (0) 2018.10.11
C++ friend 클래스와 함수  (1) 2018.10.10
C++ 클래스 접근제한자  (0) 2018.10.10

C++ 함수 오버로딩




안녕하세요 열코입니다.

이번시간에는 C++ 에서 함수 오버로딩에 대해 알아보겠습니다.


☞ 함수 오버로딩이란?

같은 함수의 이름을 가지고 있지만 파라미터(매개변수) 및 리턴 타입 등의 특징이 다른 여러개의 함수를 만드는 것입니다.

예를들어 우리가 C++ 프로그래밍을 할 때에 cout 출력 함수를 통해 int, char, string, double 등의 여러가지 타입의 자료형을

다른 함수가 아닌 cout 하나의 함수를 통해 출력할 수 있는 기능을 구현하는데 사용됩니다.


* 너무 많이 함수를 오버로딩 할 경우 코드가 복잡해지며 어떤 오버로드 함수가 호출되었는지 알기 힘들어지므로

적절한 상황에 적당히 사용하는것을 권합니다.


 함수 오버로딩 예제


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
#include <iostream>
using namespace std;
 
int yc(int i) {
    return i + 1;
}
char yc(char c) {
    return c + 1;
}
double yc(double d) {
    return d + 1.1;
}
 
 
int main(void) {
    int x = 5;
    char y = 'a';
    double z = 3.3;
 
    cout << yc(x) << "\n";
    cout << yc(y) << "\n";
    cout << yc(z) << "\n";
 
    return 0;
}
cs


위의 코드처럼 같은 이름을 가진 함수가 여러개 존재합니다.

main 함수에서는 yc() 라는 함수를 호출할 뿐이고 매개변수로 int, char, double 형식이 순서대로 들어갑니다.

컴파일러는 매개변수를 구분하여 어떤 함수를 호출할 지 결정합니다.


ㅇ 출력 결과


6

b

4.4



 함수 오버로딩이 가능하지 않은 경우?

Microsoft MSDN에서는 함수 오버로드 고려사항으로 다음과 같이 정의합니다.


출처 : https://msdn.microsoft.com/ko-kr/library/5dhe1hce.aspx



C++에서 함수 오버로딩을 할 수 없는 함수들을 하나씩 살펴보도록 하겠습니다.


1. 반환 값의 형식만 다른 함수 선언.


1
2
3
4
5
6
7
8
int yc() {
    return 1;
}
 
char yc() {
    return 'c';
}
 
cs


위와 같이 반환 값의 형식만 다른 함수를 오버로드 할 경우 다음과 같은 컴파일 오류가 발생합니다.


- 반환 형식으로만 구분되는 함수를 오버로드할 수 없습니다.

- 'char yc(void)': 오버로드된 함수가 'int yc(void)'과(와) 반환 형식만 다릅니다.

- 'yc': 재정의. 기본 형식이 다릅니다.



2. 형식이 같은 static(정적) 멤버 함수를 오버로드하는 경우.


1
2
3
4
5
6
class YC {
    static void yc(int i) {}
 
    void yc(int i) {}
};
 
cs


위와 같이 반환 값 형식과 매개변수 형식이 같은 정적 메소드와 비 정적 메소드를 오버로드할 수 없습니다.

다음과 같은 컴파일 오류가 발생합니다.


- 매개 변수 형식이 같은 정적 및 비정적 멤버 함수를 오버로드할 수 없습니다.



3. 매개변수 형식이 배열과 포인터


1
2
int yc(int *p);
int yc(int p[]);
cs


위와 같이 함수 몸체가 없이 정의만 하는 경우 컴파일 오류는 발생하지 않지만, 컴파일러가 동일한 함수로 인지합니다.

매개변수 배열 선언은 포인터 선언으로 조정되기 때문에 단순히 위의 함수를 재정의 하는 구문입니다.


아래 코드의 경우도 마찬가지로 동일한 함수를 재정의하는 구문입니다.


1
2
3
int yc(int );
int yc(int *);
 
cs


매개변수에 const로 구분을 짓는것 또한 마찬가지입니다.


1
2
3
4
5
6
int yc(int x) {
    return x;
}
int yc(const int x) {
    return x;
}
cs


위와 같이 함수를 선언한 경우에는 컴파일 에러를 발생시킵니다.


- 'int yc(int)' 함수에 이미 본문이 있습니다.


위의 케이스들은 함수 오버로딩이 아닌 단순 함수 재정의라고 볼 수 있습니다.



이상 'C++ 함수 오버로딩'에 대해 알아보았습니다.

질문 또는 오타나 잘못된 정보가 있는 경우 댓글로 달아주세요!

공감♡ 버튼을 눌러주시면 더욱 유용하고 좋은 포스팅으로 찾아 뵙겠습니다.



'C, C++' 카테고리의 다른 글

C 표준 입력 함수 scanf  (0) 2018.10.23
C 표준 출력 함수 printf()  (0) 2018.10.22
C++ 가상 함수(Virtual Function)  (8) 2018.10.19
C++ 연산자 오버로딩  (2) 2018.10.12
C/C++ 메모리 동적할당  (0) 2018.10.11
C++ friend 클래스와 함수  (1) 2018.10.10
C++ 클래스 접근제한자  (0) 2018.10.10
C++ 클래스와 객체  (0) 2018.10.09

to Top