프로그래밍 공부
작성일
2023. 5. 3. 20:48
작성자
WDmil
728x90

C++에서는 Class 내부의 private 멤버에 대한 접근허용을 위해 다른 클래스 나 함수가 접근할 수 있도록 Friend 선언을 허용한다.

 

Friend선언을 사용하면, Pirvate 멤버에 대한 접근 제어를 우회하여, 다른 클래스나 함수에서 해당 멤버를 직접 접근할 수 있다.

 

Friend 선언은 다음과 같은 상황에서 사용된다.

  • 두개 이상의 클래스가 서로의 private 멤버에 접근해야 할 때
  • 특정 함수가 클래스의 private 멤버에 접근해야 할 때
  • 특정 클래스의 인스턴스를 생성해야 할 경우 다른 클래스의 private 멤버를 초기화해야할 때.

 

Friend 선언은 다음과 같다.

위와 같은 방법으로 선언을 하였을 시, 전역함수처럼 취급되어 사용이 가능해진다.

그러나, 이러한 방법으로 전역함수 취급되어 사용하는것 보다는, 각 지정한 Class에 friend선언하여, 해당 class에서 사용하도록 허용하는 정도로 사용된다.

위 방식이 가장 많이 사용하는 방식으로, 직관적이고 허용범위가 작아서 오류 가능성이 작다.

그러나, Class의 모든함수를 다른 Class에 공유할 때, 한개의 변수만 찍어서 공유하는것은 불가능하다.

Friend 선언을 하였을 경우, 해당 함수의 public 에 전부 접근이 가능해지기 때문이다.

이러한, Friend 선언은, C++에서 정보 은닉(Information hiding)을 위한 접근제어(accecss control) 매커니즘을 우회하는 방법으로, 일반적으로 private 멤버는 클래스 외부에서 직접접근 할 수 없도록 제한되어있으나, 특정상황에서 접근해야하는 필요성이 생길 때 사용하게 된다.

 

장점

  • 클래스의 정보은닉 원칙을 유지하면서, 특정사오항에서 private 멤버의 접근을 허용할 수 있다.
  • 클래스 외부에서 직접 호출할 필요가 없어짐으로, 코드의 가독성과 유지보수성을 높일 수 있다.

단점

  • Friend 선언을 남발하게 되면, 클래스의 정보은닉 원칙이 해치될 수 있다.
  • 해당 멤버에 대한 접근을 허용함으로 잘못된 사용으로인한 보안문제가 발생할 수 있다.

C++에서는 anonymous_object 라는 방식으로, 어떠한 Class를 선언할 때, 클래스를 인스턴스화 시키지 않고 그냥 사용하는 방법을 지원한다.

 

이러한 어나니머스 오브젝트 방식은, 클래스의 명을 따로 선언하지 않음으로 프로그래머의 편의성을 증가시키고, 코드의 가독성을 올려주는 효과가 있다.

 

인스턴스화 사용은 다음과 같다.


C++에서 Class를 사용할 때, Class안에 Class를 중첩하여 선언하여, 코드의 가독성과 유지보수성을 향상시킬 수 있다.

 

보통 이러한 방법은 자료형을 중첩하여 사용할때 사용하게 된다.

위 코드에서 Character 에 대한 class를 선언하고, Class 내부에 idle walk등, enum class Movement 를 선언하고, 그에대한 값을 직접 지정하여, private에 대한 movementSpeed를 참조하고, 그 값을 speed에 갱신하는 코드이다.

 

이러한 코딩방식은 코드의 직관성을 높여주고, 수정할 때 값을 추가하기 원할하게 만들어준다.


C++ 에서는 Operator_Overloading 을 지원한다.

 

이는 어떠한 접근 연산자를 제외한 모든 연산자에 대한 오버로딩을 허용한다는 의미로, 보통 사용하는 x = 1 + 2 같은 연산자의 + 를 내가 원하는대로 설계할 수 있다는것 이다.

 

일반적으로 Class를 선언하고, Class x, y, z 를 생성한 뒤, x = y + z 의 연산을 컴파일러에 집어넣으면, 컴파일러는 이 연산작용이 Class 내부의 어떠한 변수를 더해야하는지 알 수 없어지기 때문에, 값을 연산할 수 없어 오류가 나타나게 된다.

 

그러나, 오퍼레이터 오버로딩을 사용하면, 이러한 연산자에 대한 연산방식을 지정해줄 수 있기 때문에, 더 쉽고 간단한 프로그래밍 방법으로 사용할 수 있게 된다.

 

이러한 Operator_Overloading 을 사용하면, 가독성이 더 뛰어나고 코딩의 값 연산에 대해 더 직관적으로 이해할 수 있게된다.

 

다음은 오퍼레이터 오버로딩을 사용하지 않고 class간 연산을 구현하였다.

이러한 Class 연산은 정보은닉에 위반한. 캡슐화를 깨는 코딩방법이 될 수 있다. 그럼으로 이러한 코딩 방법은 피해야 옳을것이다.

 

이 때 사용할 수 있는것 이 오퍼레이터 오버로딩으로

다음은 오퍼레이터 오버로딩을 사용하여 같은 연산을 구현하였다.

위의 30번째 줄부터 34번째 줄이 오퍼레이터 오버로딩을 사용하여 +연산을 구현한 것 이다. 이러한 방법으로 어떠한 Class간의 연산을 컴파일러 에게 입력시켜 더 간단하고 좋은 코딩을 완성할 수 있다.


C++에서 사용하는 연산자(Operator) 오버로딩을, Friend와 결합하여, 전역함수 에 의한 연산자 오버로딩을 사용할 수 있다.

위 코딩방식과 마찬가지로 연산자 오버로딩을 통한 인자값의 이름을 정해주어, int값을 되돌려줄 수 있다.

 

또한, friend 선언을 하였음으로 16번의 함수선언은, 전역함수 로 선언한 것 과 마찬가지 이기 때문에, 이러한 friend 함수는 38번째줄 에서 함수를 만들어준것 과 같은 효과를 가진다.

 

또한, 18번째 줄에서 사용하는 friend Won operator 을 생성하고, 이를 return값으로 int value를 돌려주었는데, 생성해도 오류가 나타나지 않는것 을 볼 수 있다.

 

이는, 리턴이 Won 일 경우, 아무런 값을 가지지 않은 리턴 Won이 생성되고, 여기에서 return되는 값이 lhs.value - rhs.value; 이기 때문에

 

이것은 Won (anonymous_object).value = lhs.value - rhs.value; 와 같아진다.

 

그럼으로, 리턴 하는 값이 int 처럼 보여도, int 값이 아닌 return으로 돌려받는 class 이기 때문에 오류가 나타나지 않게되는것 이다.

 

만약, Won 이라는 Class에 private변수가 value 한개만이 아닌 여러개의 변수가 존재할 경우, 이 anonymous_object는 할당을 value만 받기 때문에, value 값만 가진 채 생성되게 되는것이다.

 

즉, 32줄의 result2 에 변수가 2개 이상일 경우, value 값만 정수형이고 나머지는 NULL로 초기화된 값이나, 알 수 없는 값을 가지는 변수가 되는것이다.


friend 방식이 아닌 멤버함수 에 의한 연산자 오버로딩 또한 가능하다. 이는 같은 Class 내부에서 동작하게 되는것 임으로, 오버로딩에 대한 큰 차이 없이 같은 연산이 이루어지게 된다.

 

이러한 연산자 오버로딩을 사용하여, 임의의 값을 더한것을 출력할 수 있다.

 

위 방법과 같이 전위 와 후위 연산자, 단순한 산술 연산자를 오버로딩하여, Vector 값을 구현하고, 이를 더하거나 빼줄 수 있게 된다.

728x90