[C++] Implicit Conversion(묵시적 형변환)

2024. 6. 27. 17:31·Programming Language/C++

Implicit Conversion(묵시적 형변환)


묵시적 형변환과 명시적 형변환

  • 묵시적(암시적) 형변환: implicit conversion

    • 형변환을 겉으로 드러내지 않음
  • 명시적 형변환: explicit conversion

    • 형변환을 명시한다

변환 생성자

#include <iostream>
#include <string>
using namespace std;

class Item {
   public:
    Item(int num) : num(num) {  // 변환 생성자
        cout << "Item(int)" << '\n';
    }
    Item(string name) : name(name) {  // 변환 생성자
        cout << "Item(string)" << '\n';
    }
    Item(int num, string name) : num(num), name(name) {
        cout << "Item(int, string)" << '\n';
    }
    void print() {
        cout << num << " : " << name << endl;
    }

   private:
    int num;
    string name;
};

int main(void) {
    Item i1 = Item(1);
    Item i2(2);
    Item i3 = 3; // 변환 생성자(int num)
    i3 = 3;
    // 3을 item객체로 변환시킴(임시객체 생성) --> 이동생성자를 통해 i3로 대입
    // 묵시적 변환

    Item i4 = (Item)4;  // Item(int num) 생성자가 형 변환까지 하고 있음.
    // 명시적 변환
  • 전부 Item(int num) 생성자를 호출

    • 우리가 알고 있는 일반적인 일반적인 생성자의 역할도 하지만, 변환 생성자의 역할도 한다.
  • Item i3 = 3;

    • 변환 생성자에서 임시 객체를 생성한 후 임시 객체를 통해서 i3를 초기화
  • i3 = 3

    • 컴파일러는 정수 3이 i3로 변환될 수 있는지를 찾는다.

    • 변환 생성자가 존재 -> 변환 생성자 Item(int)가 호출되어 임시 객체가 생성된다

    • 기본 대입 연산자를 통해 i3에 대입된다

  • 아래 코드도 변환 생성자를 통해 대입된다

Item i5(5);
i5 = string("stone");
  • 그러면 파라미터가 2개인 생성자를 호출하면?
Item i6(1, "grass");
Item i7 = { 2, "dirt" };
// 다음도 가능
i7 = { 2, "dirt" }; // C++11 문법, 묵시적 변환
Item i8{ 3, "wood" };
  • 매개변수가 2개인 경우에 대해서도 위에서 본 것과 같이 변환 생성자를 통해서 작동한다

  • 실제로 테스트를 해보자

i1.print();
i2.print();
i3.print();
i4.print();
i5.print();
i6.print();
i7.print();
i8.print();

형변환 연산자 오버로딩

  • 다음은 불가능하다
int itemNum = (int)i8;
  • 형변환도 연산자이기 때문에, 연산자 오버로딩을 해줄 수 있다.
class Item {
        // Item -> int 형변환 연산자 오버로딩
    operator int() const { // explicit operator int() : 명시적으로만 가능하게
        return num;
    }
}
  • 반환 타입을 operator 키워드 뒤에 적어줌

    • 연산자에서 반환 타입을 알 수 있기 때문에 operator 앞에 int 등의 타입을 안 적는 것

    • 객체 자체가 안바뀌도록 const를 붙여주는게 일반적이다

  • 이렇게 하면 위에서 불가능 했던 것이 가능해짐

int itemNum1 = (int)i8;
// 묵시적도 가능하다
int itemNum2 = i7;
  • String 타입으로도 바꿔보자
// Item -> string
operator string() const {
        return to_string(num) + " : " + name;
        // 참고) to_string : 숫자를 문자열로 반환하여 return
}

void println(string s) {
    cout << s << endl;
}
  • 출력을 해보자
int itemNum = (int)i8;  // 명시적
int itemNum2 = i7;      // 묵시적
cout << itemNum << endl;
cout << itemNum2 << endl;

println((string)i8);  // 명시적 형변환
println((int)i8);
  • 만약 다음과 같이 출력한다면?
println(i8);
  • string으로 묵시적 형변환이 일어난다

  • 만약 다음과 같은 함수가 추가로 존재한다면?

void println(int n) {
    cout << n << endl;
}
  • println(i8)에서 오류가 발생한다.

    • 묵시적 형변환시 i8을 string으로? Int로? 어떤 걸로 변환해야 하는지 모호성 발생

explicit 키워드

  • 형변환 연산자 앞에 explicit 키워드를 붙여주면 묵시적으로 해당 형변환 연산자가 실행되지 않도록 만든다

  • 주로 원하지 않은 다른 타입으로 묵시적 변환이 발생하는 것을 방지하기 위해 사용한다

explicit operator string() const {
    return to_string(num) + " : " + name;
}
  • 변환 생성자에 explicit을 붙여주면 묵시적으로 Item형 임시 객체를 만드는 것이 불가능해져서 에러가 발생한다
class Item {
   public:
    explicit Item(int num) : num(num) {  // 변환 생성자 // explicit Item(int num) : 명시적으로만 가능하게
        cout << "Item(int)" << '\n';
    }
    explicit Item(string name) : name(name) {  // 변환 생성자
        cout << "Item(string)" << '\n';
    }
    explicit Item(int num, string name) : num(num), name(name) {
        cout << "Item(int, string)" << '\n';
    }
        /* 이하 생략 */
}

int main(void) {
    Item i1 = Item(1);
    Item i2(2);
    Item i3 = 3; // 에러 발생 : 묵시적 형변환 불가
    i3 = 3; // 에러 발생 : 묵시적 형변환 불가

'Programming Language > C++' 카테고리의 다른 글

[C++] 상속이 필요한 이유(1)  (0) 2024.06.27
[C++] 상속(Inheritance)과 접근제어(Access Control)  (0) 2024.06.27
[C++] 이동 시맨틱(Move Semantics): 이동 생성자, 이동 대입 연산자  (0) 2024.06.27
[C++] 대입 연산자 오버로딩  (0) 2024.03.12
[C++] 복사 생성자 오버로딩  (0) 2024.03.12
'Programming Language/C++' 카테고리의 다른 글
  • [C++] 상속이 필요한 이유(1)
  • [C++] 상속(Inheritance)과 접근제어(Access Control)
  • [C++] 이동 시맨틱(Move Semantics): 이동 생성자, 이동 대입 연산자
  • [C++] 대입 연산자 오버로딩
lumana
lumana
배움을 나누는 공간 https://github.com/bebeis
  • lumana
    Brute force Study
    lumana
  • 전체
    오늘
    어제
    • 분류 전체보기
      • Spring
        • MVC
        • DB
        • 핵심 원리
        • JPA
      • WEB
        • HTML
        • CSS
        • HTTP
        • Application
      • Computer Science
        • Network
        • Database
        • OS
        • 시스템 프로그래밍
        • 컴퓨터구조
      • Algorithm
        • Divide&Conquer
        • Sort
        • Greedy
        • DP
        • Backtracking
        • NP-Complete
        • Graph
      • Data Structure
        • 자료구조
        • C++ STL
        • Java Collection
      • 소프트웨어 공학
        • 시험 공부 정리
        • Theorem
      • Programming Language
        • Python
        • Java
        • C
        • C++
        • Rust
        • Theory
      • Unix_Linux
        • Common
      • React
      • PS
        • BOJ
        • Tip
        • 프로그래머스
        • CodeForce
      • Book Review
        • Clean Code
      • Math
        • Linear Algebra
      • AI
        • DL
        • ML
        • DA
        • Concepts
      • 우아한테크코스
        • 프리코스
      • Project Review
      • LegacyPosts
      • Android
      • Apple
        • Mac
        • IPhone
        • IPad
      • 모니터
      • Diary
  • 블로그 메뉴

    • 홈
    • 태그
    • 방명록
  • 링크

  • 공지사항

  • 인기 글

  • 태그

  • 최근 댓글

  • 최근 글

  • hELLO· Designed By정상우.v4.10.3
lumana
[C++] Implicit Conversion(묵시적 형변환)
상단으로

티스토리툴바