변환 생성자(conversion constructor)란, 클래스의 객체를 다른 타입으로 자동으로 변환시켜주는 생성자를 의미합니다.
즉, 특정 클래스의 객체를 다른 클래스의 객체로 변환할 수 있도록 해주는 역할을 합니다.
변환 생성자는 다음과 같은 형태로 정의됩니다.

 

class TargetClass {
public:
    TargetClass(SourceClass source_object);
};
위의 코드에서 TargetClass는 변환하려는 타입이고, SourceClass는 변환할 객체의 원래 타입입니다.
이러한 변환 생성자는 해당 클래스를 대상으로 암시적으로 호출되며, 사용자가 직접 호출할 수는 없습니다.

 

 

예를 들어, 다음과 같은 Rational 클래스가 있다고 가정해보겠습니다

 

class Rational {
public:
    Rational(int numerator, int denominator);
};

 

이 클래스는 분자와 분모를 받아서 유리수(Rational number)를 생성하는 생성자입니다.

이제 이 클래스의 변환 생성자를 추가하여, Rational 객체를 double 타입으로 변환할 수 있도록 만들어 보겠습니다.

 

class Rational {
public:
    Rational(int numerator, int denominator);
    operator double() const {
        return static_cast<double>(numerator) / denominator;
    }
private:
    int numerator;
    int denominator;
};

 

위의 코드에서 operator double() 함수가 변환 생성자입니다. 이 함수는 Rational 객체를 double 타입으로 변환합니다.

즉, 다음과 같이 Rational 객체를 double로 변환하여 사용할 수 있습니다.

 

Rational r(3, 2);
double d = r; // Rational 객체 r을 double 타입으로 자동 변환

 

위와 같이 변환 생성자를 사용하면, 클래스 객체의 타입 변환을 간단하게 처리할 수 있으며, 코드의 가독성과 유지보수성을 높일 수 있습니다. 하지만, 자주 사용되는 타입 변환이 아닌 경우, 불필요한 오버헤드를 초래할 수 있으므로, 적절한 사용을 고려해야 합니다.

 

 

아래 예제에서는 Matrix 클래스를 정의하고, 두 개의 Matrix 객체를 더하는 연산을 수행합니다. 이 때, 더하기 연산자를 통해 두 개의 Matrix 객체를 더할 수 있도록 Matrix 클래스에 변환 생성자와 변환 연산자를 구현합니다.

 

#include <iostream>
#include <vector>

class Matrix {
public:
  Matrix(int rows, int cols) : rows_(rows), cols_(cols), data_(rows * cols) {}

  // 변환 생성자: std::vector<double>를 Matrix로 변환
  Matrix(const std::vector<double>& data, int rows, int cols) : rows_(rows), cols_(cols), data_(data) {}

  // 변환 연산자: Matrix를 std::vector<double>로 변환
  operator std::vector<double>() const {
    return data_;
  }

  // 더하기 연산자
  Matrix operator+(const Matrix& other) const {
    Matrix result(rows_, cols_);

    for (int i = 0; i < rows_ * cols_; ++i) {
      result.data_[i] = data_[i] + other.data_[i];
    }

    return result;
  }

  // 인덱싱 연산자
  double& operator()(int row, int col) {
    return data_[row * cols_ + col];
  }

  // 상수 인덱싱 연산자
  const double& operator()(int row, int col) const {
    return data_[row * cols_ + col];
  }

private:
  int rows_;
  int cols_;
  std::vector<double> data_;
};

int main() {
  // 2x2 Matrix 생성
  Matrix m1(2, 2);
  m1(0, 0) = 1.0;
  m1(0, 1) = 2.0;
  m1(1, 0) = 3.0;
  m1(1, 1) = 4.0;

  // 2x2 Matrix 생성
  Matrix m2(2, 2);
  m2(0, 0) = 5.0;
  m2(0, 1) = 6.0;
  m2(1, 0) = 7.0;
  m2(1, 1) = 8.0;

  // Matrix 더하기
  Matrix result = m1 + m2;

  // 결과 출력
  std::vector<double> data = result; // Matrix를 std::vector<double>로 변환
  std::cout << "Result:" << std::endl;
  for (int i = 0; i < data.size(); ++i) {
    std::cout << data[i] << " ";
    if ((i + 1) % 2 == 0) {
      std::cout << std::endl;
    }
  }
}
이 예제에서는 Matrix 클래스에 std::vector<double> 을 인수로 받는 변환 생성자를 추가합니다. 이 생성자는 std::vector<double>
을 Matrix 객체로 변환합니다. 또한, Matrix 객체를 std::vector<double> 로 변환하는 변환 연산자도 추가합니다. 이 변환 연산자는
Matrix 객체를 std::vector<double>으로 변환합니다. 이렇게 하면 Matrix 객체를 std::vector<double>로 변환할 수 있으며, 이는 더하기 연산의 결과를 출력하기 위해 사용됩니다.
더하기 연산자에서는 두 개의 Matrix 객체를 더한 결과를 새로운 Matrix 객체로 반환합니다. 이때 반환된 Matrix 객체는 std::vector<double>로 변환할 수 있으며, 이를 통해 결과를 출력합니다.
이 예제에서는 또한 Matrix 클래스에 인덱싱 연산자와 상수 인덱싱 연산자를 정의하여 Matrix 객체의 요소에 접근할 수 있도록 했습니다. 이처럼 변환 생성자와 변환 연산자를 사용하면, 클래스와 클래스 간의 변환을 편리하게 처리할 수 있습니다.
\하지만 이러한 기능을 남용하면 코드의 가독성을 떨어뜨릴 수 있으므로, 필요한 경우에만 사용하는 것이 좋습니다.

 

끝으로, 제 C++ 역량 향상에 많은 도움을 줬던 책(한권을 뽑으라고 하면 뽑는 책) 소개하며 포스팅을 마치겠습니다 :)

 

http://www.yes24.com/Product/Goods/117986059

 

전문가를 위한 C++ - YES24

더 쉽게, 더 빠르게, 더 깔끔하게!프로그래머가 알아야 할 C++와 C++20의 모든 것C++는 마스터하기 어렵기로 악명 높지만, 풍부한 기능 덕분에 게임이나 상용 소프트웨어 애플리케이션을 개발하는

www.yes24.com

 

+ Recent posts