C++ 프렌드 개념
C++에서 "프렌드(Friend)"는 클래스의 멤버 함수가 아니지만, 해당 클래스의 멤버에 접근할 수 있는 특별한 권한을 부여하는 기능을 나타냅니다. 프렌드 함수나 클래스는 클래스의 `private` 및 `protected` 멤버에 접근할 수 있으며, 일반적인 접근 제어 규칙을 무시합니다. 프렌드 함수나 클래스는 해당 클래스가 믿을 수 있는 "친구"로 간주되어, 클래스의 내부 구현 세부 사항에 접근해야 하는 경우 유용하게 사용됩니다.
프렌드의 주요 특징은 다음과 같습니다:
1. 프렌드 함수(Friend Function): 특정 클래스의 `private` 또는 `protected` 멤버에 접근할 수 있는 전역 함수로 정의됩니다. 클래스 선언 내에서 `friend` 키워드를 사용하여 선언됩니다.
class MyClass {
private:
int privateData;
friend void friendFunction(const MyClass& obj); // 프렌드 함수 선언
public:
MyClass(int val) : privateData(val) {}
};
// 프렌드 함수 정의
void friendFunction(const MyClass& obj) {
std::cout << "Accessing privateData from friend function: " << obj.privateData << std::endl;
}
int main() {
MyClass obj(42);
friendFunction(obj); // 프렌드 함수 호출
return 0;
}
2. 프렌드 클래스(Friend Class): 특정 클래스의 `private` 또는 `protected` 멤버에 접근할 수 있는 클래스로 정의됩니다. 클래스 선언 내에서 `friend` 키워드를 사용하여 선언됩니다.
class MyClass {
private:
int privateData;
friend class FriendClass; // 프렌드 클래스 선언
public:
MyClass(int val) : privateData(val) {}
};
class FriendClass {
public:
void accessPrivateData(const MyClass& obj) {
std::cout << "Accessing privateData from FriendClass: " << obj.privateData << std::endl;
}
};
int main() {
MyClass obj(42);
FriendClass friendObj;
friendObj.accessPrivateData(obj); // 프렌드 클래스의 멤버 함수 호출
return 0;
}
프렌드 함수나 클래스는 주의해서 사용해야 합니다. 클래스의 `private` 및 `protected` 멤버에 대한 접근 권한을 부여하기 때문에, 캡슐화와 정보 은닉 원칙을 무시할 수 있으며, 코드의 복잡성을 증가시킬 수 있습니다. 따라서 프렌드를 사용할 때는 신중하게 고려하고, 최대한 클래스의 인터페이스를 통해 데이터와 동작을 조작하도록 노력해야 합니다.
연산자 중복
연산자 중복은 C++와 같은 언어에서 사용자 정의 데이터 형식(클래스 또는 구조체)에 대한 연산자 동작을 재정의하는 것을 의미합니다. C++에서는 이를 통해 사용자 정의 형식을 내장 데이터 형식처럼 다룰 수 있게 됩니다. 이를 통해 코드의 가독성을 향상시키고 객체 지향 프로그래밍의 장점을 활용할 수 있습니다.
연산자 중복을 수행하기 위해 다음 두 가지 주요 방법이 있습니다.
1. 멤버 함수를 사용한 연산자 중복: 연산자를 해당 클래스의 멤버 함수로 정의하는 방법입니다. 이 방법은 주로 객체 간의 연산에 사용됩니다. 예를 들어, 덧셈 연산자 '+'를 MyClass 클래스에 대해 중복 정의하는 예제를 보겠습니다.
class MyClass {
public:
int value;
MyClass(int val) : value(val) {}
// + 연산자 중복 (멤버 함수로 정의)
MyClass operator+(const MyClass& other) {
MyClass result(value + other.value);
return result;
}
};
int main() {
MyClass obj1(5);
MyClass obj2(10);
MyClass obj3 = obj1 + obj2; // + 연산자 중복 사용
return 0;
}
2. 전역 함수를 사용한 연산자 중복: 연산자를 클래스의 멤버 함수로 정의하지 않고 전역 함수로 정의하는 방법입니다. 이 방법은 주로 두 개 이상의 객체 간의 연산에 사용됩니다. 같은 덧셈 연산자 '+'를 MyClass 클래스에 대해 중복 정의하는 예제를 보겠습니다.
class MyClass {
public:
int value;
MyClass(int val) : value(val) {}
};
// + 연산자 중복 (전역 함수로 정의)
MyClass operator+(const MyClass& obj1, const MyClass& obj2) {
MyClass result(obj1.value + obj2.value);
return result;
}
int main() {
MyClass obj1(5);
MyClass obj2(10);
MyClass obj3 = obj1 + obj2; // + 연산자 중복 사용
return 0;
}
연산자 중복은 다른 연산자에도 동일한 방식으로 적용될 수 있으며, 사용자 정의 형식에 대한 연산을 더 직관적으로 만들어줍니다. 이를 통해 사용자 정의 클래스나 구조체를 더 쉽게 다룰 수 있고, 코드의 가독성을 높일 수 있습니다.