📚책읽기

[C++] 랜덤함수, explicit(명시적 데이터형 변환), 변환함수, 프렌드 (friend), 연산자 오버로딩, 오버로딩 제약, Vector클래스

공대 컴린이 2023. 2. 2. 10:08
728x90

랜덤 함수

C++에서는 표준 라이브러리 함수인 rand(), srand(), time()을 사용한다.

  • rand()

그냥 rand() 함수를 사용하면 난수가 뽑히는 것 같지만, rand() 함수는 초기 씨앗값에 어떤 알고리즘을 적용하여 하나의 무작위 값을 뽑아낸다. 그 무작위 값은 다시 다음 번 함수 호출에 사용된다. 따라서 난수를 10번 호출하면 10번 모두 동일한 난수 집합이 생기는 문제점이 있다.

  • srand()

srand() 함수를 이용하면 디폴트 씨앗값을 무시하고 다른 난수 집합을 발생할 수 있다. 주로 time(0)의 리턴값을 씨앗값으로 설정하여 시간을 초 단위로 받아 씨앗값이 매번 달라지도록 설정한다.

srand(time(0));

explicit 키워드

C++은 자동 데이터형 변환을 제공하여 생성자의 데이터형을 자동으로 변환해준다. 이는 유용한 기능처럼 보이지만 예상하지 못한 변환이 일어나 프로그램에 부작용을 일으킬 수 있는데, 이를 방지하기 위한 키워드가 explict 키워드이다.

생성자를 선언할 때 explicit 생성자(매개변수); 와 같이 선언한다면 이 함수는 암시적 데이터형 변환을 허용하지 않고 명시적 데이터형 변환만으로 데이터형을 바꿀 수 있다.

변환 함수 (Conversion Function)

하나의 수(number)를 클래스 객체로 변환하는 것은 쉽게 가능하지만, 반대로 클래스 객체를 하나의 수로 변환하는 방법은 변환 함수를 사용해야 한다.

생성자는 어떤 데이터형을 클래스형을 변환하는 역할만을 수행하므로, C++에서 변환함수라고 불리는 C++ 연산자 함수를 사용해야 한다. 

변환함수는 사용자 정의 강제 데이터형 변환으로 일반적인 강제 데이터형  변환(type cast)처럼 사용하면 된다.

Stonewt wolfe(285.7);
double host = double(wolfe);		// 변환함수 명시적 사용
double thinker = (double)wolfe;		// 변환함수 명시적 사용
double star = wolfe;			// 변환함수 암시적 사용

프로그램에서 명시적 변환과 암시적 변환이 모두 가능한 경우엔, 명시적 변환을 사용하여 암시적 변환의 가능성을 없애는 것이 가장 좋다. 암시적 변환 함수는 신중하게 사용해야 하며, 명시적으로만 호출할 수 있는 함수를 사용하는 것이 가장 바람직하다.

프렌드 (friend)

프렌드는 멤버 함수가 아닌 함수가 private 데이터에 접근할 수 있게 해 주는 C++의 메커니즘이다.

본래 C++은 클래스 객체의 private 부분에 접근하는 것을 통제한다. 일반적으로 private 객체에 접근하기 위한 유일한 통로는 public 클래스 메서드이다. 그러나 때로는 프로그램 상에서 이런 엄격한 제약이 특정 프로그래밍 문제를 해결하지 못하는 경우가 있어, C++은 프렌드라는 또 하나의 접근 통로를 만들어 제시하였다.

프렌드는 프렌드 함수/프렌트 클래스/프렌드 멤버함수 와 같은 세가지 형태로 사용될 수 있다.

쉽게 말해 프렌드 함수는 멤버 함수와 동등한 접근 권한을 가지지만, 멤버는 아닌 함수이다.

언뜻 보면 프렌드가 객체지향 프로그래밍의 철학을 무시하고 데이터 은닉을 무시하는 것처럼 보이지만, 프렌드 함수는 클래스를 위한 확장 인터페이스의 일부라고 생각해야 한다. C++의 문법 때문에 막히는 연산 등을 프렌드 함수로 사용하면, 클래스 메서드와 프렌드는 단순히 클래스 인터페이스를 나타내는 두 개의 서로 다른 메커니즘이라고 볼 수 있다.

연산자 오버로딩 (operator overloading)

연산자 오버로딩은 C++가 가지고 있는 다형 특성의 한 예이다.

함수 오버로딩이란 시그내처(매개변수 리스트)를 다르게 제공하여 이름이 같은 여러 함수를 정의할 수 있다는 것이고, 함수 다형이라고도 부른다. 함수 오버로딩의 목적은 적용할 데이터형이 서로 다르더라도 동일한 함수 이름으로 동일한 연산을 수행하기 위함이다.

연산자 오버로딩은 C++의 오버로딩 기능을 활용하여 연산자에 까지 확장한 방법이다. 오버로딩된 연산자를 일반적인 문법으로 사용함으로써 연산자 함수를 호출하여 프로그램의 간결성을 높일 수 있다.

operatorop (argument-list)

연산자 오버로딩의 문법에서 argument-list는 연산자에 대한 피연산자를 나타낸다. 예를 들면 operator+() 이나 operator*() 를 사용하여 + 와 * 의 연산자를 오버로딩 할 수 있다.

오버로딩 제약

오버로딩 연산자는 적어도 하나의 피연산자가 '사용자 정의 데이터형'일 것을 요구한다. 즉, 사용자 정의 데이터형이 아닌 기본 변수의 자료형으로만 연산자 오버로딩을 만드는 것은 문법 규칙을 위반할 수 있어 불가능하다. (예시, double형 변수 두개를 뺄셈 연산자(-)로 합계(+)를 구하는 오버로딩 함수는 작성될 수 없음)

또한 '연산자 우선순위'를 변경할 수 없다.

그리고 연산자 기호를 새로 만들 수 없다.

연산자 오버로딩과 프렌드를 사용하는 클래스 : Vector 벡터

벡터(vector)는 크기와 방향을 함께 가지는 물리량이다. 위치 변화를 나타내는 벡터를 변위 벡터(displacement vector)라고 한다. 변위 벡터에서 중요한 것은 어디에서 시작하고 어디에서 끝났는가이지, 경로가 어떤지는 중요하지 않다.

728x90