프로그래밍 공부
작성일
2023. 4. 28. 01:35
작성자
WDmil
728x90

C++의 클레스에서 static 변수는 선언시 부터 전역번수로 취급된다.

 

일반적으로 class에서 변수가 선언되면 변수는 class가 선언되기 전 까지 메모리에 할당이 안된다.

 그러나, 그 내부에서 변수를 static 선언하여. 전역변수 취급으로 선언할 경우 메모리 내부에 해당 static 변수의 영역 할당이 이루어진 다음 class 선언이 이루어지고 할당된 영역을 사용하게 된다.

 

이는. static 이 전역처리되어. 모든 영역에서 사용이 가능해야 하기 때문에, 미리 데이터 영역을 할당하여 권한 문제가 발생하지 않도록 하기 위함이다.

 

다음 코드 예시로부터 살펴보자.

위 코드에서. class 내부의 static과 static const 가 선언되어 있는 12번째 변수와 15번째 변수를 확인할 수 있다.

 

static const가 선언되었을 경우, 전역 상수처리가 되어있기 때문에, class의 객체가 선언되지 않음에도 전역에서 해당되는 class를 선언하고 객체 내부에 선언되는 상수를 사용할 수 있다.

 

또한, 전역변수 처리된 class 내부의 변수는 한번 선언되고 나서는 변경되지 않기 때문에, Test 1, Test 2 등 여러개의 Class가 선언되더라도 사용되는 전역변수는 한개 라는 특징이 있다.

 


C++에서 사용되는 전역 처리 중, 변수만이 전역처리될 수 있는 것 이 아니다.

 

변수 만이 아닌 함수 또한 전역으로 생성하여 처리할 수 있다. 이 또한 전역변수 와 마찬가지로 전역 함수 이기 때문에선언되는 class의 이름이 없더라도, 주소값 참조를 사용하여 접근할 수 있다.

 

그러나, 전역 함수 이기 때문에, 메모리 할당과정 중에 일반적인 함수와는 다르기 때문에, 전역 함수는 전역 변수 만을 매개변수로 사용이 가능하다. 메모리 가 시작시 바로 잡혀서 움직이기 때문에, 일반적인 매개변수는 할당이 안되기 때문이다.

 

다음 코드 예시를 살펴보자.

class의 전역함수 선언 시, 15번째 줄의 코드가 전역변수를 사용하지 않았음으로 컴파일 에러가 발생하게 된다.

오류가 발생한다.

그리고 26번째 줄 과 같이. 이미 전역변수 처리가 되었음으로 주소값 접근이 가능하기 때문에, 함수 포인터를 class가 선언되지 않았음에도 할당이 가능한것 을 볼수 있다.

 

그러나, static 처리가 되지 않았을 때 에는 해당 함수를 가지는 소유자를 확인할 수 없기 때문에 컴파일 에러가 나타나게 된다. 이는 보안적 이슈가 될 수 있기 때문에 컴파일러가 허용하지 않는다.

 

또한 멤버 포인터로, class 외부에서 class 내부에 포인터를 생성해줄 수 있다.

32번째 줄 처럼, int 포인터를 Test:: 로 Test내부에 변수를 생성하여  이미 전에 생성한 Test t1 에도 *ptr2 가 사용이 가능한 것 을 볼수 있다.

 

또한, 이는 함수에도 적용이 가능해서 36번째 줄 처럼 사용할 수 있다.


객체지향의 설계원칙 (SOLID) 라는 것 이 있다. 자세한 내용은 링크참고.

 

또한, 이러한 객체지향의 설계원칙을 따라 만들어지는 디자인 패턴 이라는 것이있다. 자세한 설명은 링크 참고.

 

이 중 싱글톤 패턴에 대해 살펴보자.

위 코드는 싱글톤 패턴을 구현한 예시 코드이다.

싱글톤 패턴의 순서는 다음과 같다.

  1. 하나의 객체를 구현한다.
  2. Public에 자기자신을 호출 시 전역변수 화 시킨 후 전역변수화 된 값의 주소를 리턴시키는 함수를 한개 제작한다.
  3. 호출 시 제작된 클래스의 자기전역변수화 함수를 호출하고. 해당되는 주소값의 원하는 함수를 출력하게 한다.

이렇게 함으로써, 동일한 동작을 수행하는 함수를 여러개 제작 하더라도. 하나의 주소값만 참조( 생성된 전역변수 )함으로 메모리 공간을 아끼는 효과가 나타난다.


C++에는 friend 선언을 통해 클레스 간의 변수나 함수를 공유하여 사용하게 할 수 있다.

 

friend 선언을 통해 각기 다른 클래스나 구조체간의 private 멤버에 대한 외부접근 권한을 부여할 수 있다.

 

이러한 friend 함수나 클래스는 해당 클래스나 구조체의 private 멤버에 접근할 수 있으며, 이를 통해 구현 상의 편의성과 효율성을 높일 수 있다.

 

장점

  1. private 멤버에 대한 접근권한을 부여하여 클래스나 구조체의 내부구현을 숨길 수 있다.
  2. 외부 함수나 클래스에서 복잡한 연산을 수행할 수 있도록 해주어 가독성과 유지보수성을 높일 수 있다.
  3. friend 함수나 클래스는 해당 클래스나 구조체의 private 멤버에 대한 접근 권한을 가지므로, 이를 통해 프로그램의 실행속도를 높일 수 있다.

단점

  1. friend 함수나 클래스의 사용이 지나치면 클래스의 캡슐화를 해칠 수 있다!
  2. 프로그램의 복잡도가 증가하여 디버깅이 어려워질 수 있다.
  3. 위 캡슐화를 해침 설명에 의거하여 차라리 객체지향이 아닌 절차지향으로 코드를 짜는게 더 나은 상황이 올 수 있다.

 

위의 단점 중 1번째 단점이 매우 큼 으로 사실상 크게 권장되는 방식의 프로그래밍 방법이 아님을 명심하고 사용해야 한다.

 

위 코드 예시를 살펴보면 MyFriendClass 에서 private에 선언된 int secret_number 은 사실 접근이 안되는 변수이다.

그러나, 12번째 줄에서의 friend 선언을 통해 어떠한 함수가 class의 private에 접근권한 을 가짐을 표기하였고.

 

그 함수는 MyFriendClass 의 private 변수의 secret_number에 접근하여 출력할 수 있게 되었다.


이러한 코드 말고도 다른 방식으로도 사용이 가능하다.

위 코드대로 동작방식이 이루어지면, 13번째 줄 과 15번째 줄은 같은 항목이 되고, 이는 A라는 class가 선언되었을 때 전역함수 처럼 취급되어 사용할 수 있게된다. 13번 줄은 위의 다른 코드와 같은 역활이고 15번째 줄 또한 다른 방식이지만 동작사항은 같다.


위 코드방식이 가장 자주 사용하는 방식으로, Class간의 friend 선언으로 서로 private의 변수를 공유하는 상황이다. 그리하여 Class A에 있는 attack이라는 함수를 B에서 허가해주었음으로, B의 private 변수에 접근이 가능하게 된다.


위 방식대로의 코드는 friend 선언을 class에 하여, A라는 Class가 B의 모든 변수를 활용할 수 있게되는 것을 표현하였다.

 

그러나, 모든 변수를 허용할 수 있어도. 한개씩의 변수는 허용할 수 없다.

728x90