이 코드는 C++에서 비트 연산자 오버로딩을 사용하는 방법을 설명하는 예제입니다. 비트 연산자 오버로딩은 클래스 내부에서 객체의 데이터 멤버에 대해 비트 연산을 수행할 수 있도록 해줍니다. 이 코드에서는 3차원 벡터를 나타내는 Vector
클래스를 정의하고, 여러 비트 연산자 및 스트림 연산자(<<
, >>
)를 오버로딩하여 벡터 객체 간의 연산을 구현합니다.
#include <iostream>
#include <string>
using namespace std;
class Vector
{
private:
int x;
int y;
int z;
public:
Vector()
{
// 기본 생성자: 멤버 변수 x, y, z는 초기화되지 않은 상태로 남아있음
}
Vector(int x, int y, int z)
:x(x), y(y), z(z)
{
// 매개변수를 받는 생성자: 입력된 x, y, z 값으로 멤버 변수를 초기화
}
// 출력 스트림 연산자 오버로딩
friend ostream& operator<<(ostream& os, const Vector& v)
{
os << v.x << " " << v.y << " " << v.z;
return os;
}
// 입력 스트림 연산자 오버로딩
friend istream& operator>>(istream& is, Vector& v)
{
string temp; // 입력값을 임시로 받을 문자열 변수
is >> temp;
v.x = stoi(temp); // 문자열을 정수로 변환 후 x에 대입
is >> temp;
v.y = stoi(temp); // y에 대입
is >> temp;
v.z = stoi(temp); // z에 대입
return is;
}
// 비트 NOT 연산자 오버로딩
Vector operator~() const
{
// 각 멤버 변수에 대해 비트 NOT 연산을 수행
return Vector(~x, ~y, ~z);
}
// 비트 AND 연산자 오버로딩
Vector operator&(const Vector& v) const
{
// 대응되는 멤버 변수 간에 비트 AND 연산을 수행
return Vector(x & v.x, y & v.y, z & v.z);
}
// 비트 OR 연산자 오버로딩
Vector operator|(const Vector& v) const
{
// 대응되는 멤버 변수 간에 비트 OR 연산을 수행
return Vector(x | v.x, y | v.y, z | v.z);
}
// 비트 XOR 연산자 오버로딩
Vector operator^(const Vector& v) const
{
// 대응되는 멤버 변수 간에 비트 XOR 연산을 수행
// 주의: z의 경우 v.z & v.z 연산을 하고 있음 (오타의 가능성 있음)
return Vector(x ^ v.x, y ^ v.y, z & v.z);
}
// 왼쪽 시프트 연산자 오버로딩
Vector operator<<(int v) const
{
// 각 멤버 변수에 대해 주어진 비트 수만큼 왼쪽으로 시프트
return Vector(x << v, y << v, z << v);
}
// 오른쪽 시프트 연산자 오버로딩
Vector operator>>(int v) const
{
// 각 멤버 변수에 대해 주어진 비트 수만큼 오른쪽으로 시프트
return Vector(x >> v, y >> v, z >> v);
}
};
int main()
{
Vector v{ 1, 2, 3 };
cout << v << endl; // operator<<(cout, v); - v의 값을 출력
operator<<(cout, v).operator<<(endl); // 동일한 출력 방식
cin >> v; // operator>>(cin, v) - 사용자로부터 입력을 받아 v에 값을 설정
cout << v << endl; // 입력된 v의 값을 출력
Vector v0{ 0, 0, 0 };
cout << ~v0 << endl; // v0에 대한 비트 NOT 연산의 결과를 출력
Vector v1{ 1, 2, 3 };
cout << (v0 & v1) << endl; // v0과 v1의 비트 AND 연산 결과를 출력
cout << (v0 | v1) << endl; // v0과 v1의 비트 OR 연산 결과를 출력
cout << (v1 ^ v1) << endl; // v1과 v1의 비트 XOR 연산 결과를 출력
Vector v2{ 2, 4, 8 };
cout << (v2 << 2) << endl; // v2의 각 성분을 2비트 왼쪽으로 시프트한 결과를 출력
cout << (v2 >> 2) << endl; // v2의 각 성분을 2비트 오른쪽으로 시프트한 결과를 출력
}
const
가 사용된 이유여기에서 각 연산자 오버로딩 함수가 const
로 선언된 이유는, 해당 함수들이 멤버 변수를 수정하지 않고, 오직 읽기만 하기 때문입니다.
const
사용의 중요성:const
를 붙이면, 해당 함수가 클래스 멤버 변수를 변경하지 않음을 보장합니다. 이렇게 하면, 불필요한 변수 변경을 방지하여 코드의 안정성을 높일 수 있습니다.const
객체에 대한 연산 지원: 함수가 const
로 선언되지 않으면, const
객체에 대해 해당 연산을 수행할 수 없습니다. 예를 들어, const Vector v{1, 2, 3};
로 선언된 객체에서 비트 연산을 수행하려면, 연산자 오버로딩 함수가 const
로 선언되어 있어야 합니다.이 예제는 C++에서 비트 연산자를 오버로딩하여 사용자 정의 데이터 타입 간에 비트 연산을 구현하는 방법을 보여줍니다. 특히 const
를 사용하여 멤버 변수를 변경하지 않는 연산임을 명시함으로써, 코드의 신뢰성과 안정성을 높였습니다. 이를 통해 비트 연산이 필요한 다양한 상황에서 객체 지향적으로 접근할 수 있습니다.
이 예제는 벡터와 같은 복잡한 데이터 구조에서 비트 연산을 효과적으로 수행하는 방법을 보여주며, C++의 연산자 오버로딩을 이해하는 데 큰 도움이 됩니다.