<개인공부>/[C++]

[C++] static_cast (타입캐스트 연산자)

BlockDMask 2017. 11. 28. 08:30
반응형

안녕하세요 BlockDMask 입니다.

오늘은 C++의 네가지 타입변환 연산자 
static_cast, dynamic_cast, reinterpret_cast, const_cast 중
static_cast에 대해 알아보겠습니다.




> static_cast

기본 형태


static_cast<바꾸려고 하는 타입>(대상);
static_cast<new_type>(expression)

특징 (논리적으로 변환 가능한 타입을 변환한다)


compile 타임에 형변환에 대한 타입 오류를 잡아줍니다.

실수와 정수, 열거형과 정수형, 실수와 실수 사이의 변환 등을 허용한다.
arr -> point로 변경 가능합니다.

function -> function pointer로 변경 가능합니다.


포인터 타입을 다른것으로 변환 하는 것을 허용하지 않습니다. (compile error)


그러나, 상속 관계에 있는 포인터 끼리 변환이 가능합니다.


downcast (static_cast<자식클래스>(부모클래스))시에는 unsafe 하게 동작할 수 있습니다. (safe 하게 사용하려면 dynamic_cast사용)


바꾸려고 하는 타입(new_type)에는 void 타입이 올 수 있지만 계산 후 제거 합니다. (return 이 없다 -> discard expression)




> 예제(1) - 일반 변수 타입간의 static_cast

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
#include<iostream>
using namespace std;
int main(void){
    double d = 13.24;
    float f = 10.12f;
    
    double tmp_double;
    int tmp_int;
    float tmp_float;
    
    tmp_int = static_cast<int>(d);    //double -> int 로 형변환
    cout << "static_cast<int>(double) : " << tmp_int << endl;
    
    tmp_float = static_cast<float>(d); //double -> float 로 형변환
    cout << "static_cast<float>(double) : " << tmp_float << endl;
    
    tmp_double = static_cast<double>(f); //float -> double 로 형변환
    cout << "static_cast<double>(float) : " << tmp_double << endl;
    
    return 0;
}
cs



>> 결과





> 예제(2) - 포인터 타입, 배열 의 static_cast

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>
#include<cstdio>
using namespace std;
int main(void){
    //1. array->point//
    int arr[10= {11,13,15,17,19,21,23,25,27,29};
    int * ptr;
    ptr = static_cast<int *>(arr);
    cout << "1. int array -> int * : ";
    for(int i=0; i<10; i++){
        cout <<  ptr[i] << " ";
    }
    printf("\n");
 
    //2. char * -> int *//
    char str[] = "BlockDMask";
    int * ptr2;
    //ptr2 = static_cast<int *>(str); //Compile error
    //cout << *ptr2 << endl;
 
 
    //3. int * -> char *//
    int tmp = 10;
    int * ptr3 = &tmp;
    //char * c = static_cast<char *>(ptr3); //Compile error
    //cout << "3. int* -> char* : " << *c << endl;
 
    return 0;
}
cs

.

>> 결과


> 예제(3) - 열거형(enum) static_cast

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
#include<iostream>
#include<cstdio>
using namespace std;
 
enum E_VAL {A=11, B, C};
 
int main(void){
    E_VAL e = A;
    cout << "E_VAL : " << e << endl;
 
    int a;
    a = static_cast<int>(e);
    cout << "1. static_cast<int>(enum) : " << a << endl;
 
    int b;
    b = static_cast<int>(B);
    cout << "2. static_cast<int>(enum) : " << b << endl;
 
    E_VAL e2;
    e2 = static_cast<E_VAL>(13);
    cout << "3. static_cast<enum>(int) : " << e2 << endl;
 
    return 0;
}
cs



>> 결과




> 예제(4) - 상속관계에서의 static_cast

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
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
#include<iostream>
#include<cstdio>
using namespace std;
 
class shape{
private:
    int a;
public:
    virtual void draw(){
        cout << "shape : called draw()" << endl;
    }
};
 
 
class triangle : public shape{
private:
    int b;
public:
    triangle(){
        b = 30;
    }
    void draw(){
        cout << "triangle : called draw()" << endl;
    }
 
    void onlyTriangle(){
        cout << "triangle : onlyTriangle()" << endl;
        cout << b << endl;
    }
};
 
 
int main(void){
 
    //1.upcast
    shape *ps;  //부모 클래스 타입 포인터
    triangle t; //자식 클래스 인스턴스
    ps = static_cast<shape *>(&t);
    cout << "//1. upcast //\n";
    ps->draw();
 
 
    //2.downcast
    shape s;        //부모 클래스 인스턴스
    triangle *pt;   //자식 클래스 타입 포인터
    cout << "\n//2. downcast //\n";
    pt = static_cast<triangle *>(&s);
    pt->draw();
    pt->onlyTriangle();
    //허용은 된다. but, 자식 클래스의 멤버 함수를 부르면 예상값과 다르게 나온다.
    //부모 클래스 인스턴스가 자식멤버함수를 부르는 것이 비 정상적인 결과를 초래할 수 있다
 
}
cs



>> 결과 : b 값이 임의의 값으로 결정되어 나오게 된다.



<참고>

http://en.cppreference.com/w/cpp/language/static_cast

감사합니다.

반응형