개인 공부/C++

[C++] Chapter 06 정리

Koalitsiya 2023. 4. 10. 15:39

const 관련 추가

const 객체와 const 객체의 특성

 다음과 같이 변수를 상수화 할 수도 있고, 

  • const int num = 10;

 이렇게 객체를 상수화 할 수도 있다.

  • const Simple simple(20);

 이것은 객체의 const 선언이 "이 객체의 데이터 변경을 허용하지 않겠다"와 같은 의미를 가지기 때문이다.

 

const와 함수 오버로딩

 함수의 오버로딩이 성립하려면 매개변수의 수나 자료형이 달라야하며 아래와 같이 const의 선언 유무도 함수 오버로딩의 조건에 해당된다.

  • void SimpleFunc() {}
  • void SimpleFunc() const {}

 

 

클래스와 함수에 대한 friend 선언

클래스의 friend 선언

 C++의 friend 선언이 의미하는 바는 아래와 같다.

  • A 클래스가 B 클래스를 대상으로 friend 선언을 하면, B 클래스는 A 클래스의 private 멤버에 직접 접근이 가능하다.
  • 단, A 클래스도 B 클래스의 private 멤버에 직접 접근이 가능하려면, B 클래스가 A 클래스를 대상으로 friend 선언을 해줘야한다.
Class A {
private:
	int num;
    friend class B;
public:
	A(int n) : num(n) 
    {}
    ...
};

 위 클래스는 B 클래스를 friend 클래스로 선언하였다. 따라서 B 클래스 내에서 A 클래스의 모든 private 멤버에 직접 접근이 가능하다. 추가로 friend 선언은 클래스 내에 어떤 영역에 위치해 있어도 상관없다.

 

Class B {
private:
	int n;
public:
	void showInfo(A &frn) {
    	cout << frn.num << '\n';
};

 또한 위 A 클래스의 friend class B; 선언은 B가 클래스 이름임을 선언하는 역할도 한다.

 

friend 선언은 언제?

 위에서 볼 수 있듯 friend 선언은 객체 지향의 특징 중 하나인 '정보은닉'을 무너뜨리는 문법이다.

그렇기에 지나치게 사용하면 굉장히 위험해질 수 있으며, 그렇기에 필요한 상황에서 소극적으로 사용해야한다.

 

함수의 friend 선언

 전역함수와 클래스의 멤버함수를 대상으로도 friend 선언이 가능하며 friend 선언된 함수는 자신이 선언된 클래스의 private 영역에 접근이 가능하다. 또한 "friend void ShowInfo(const Point&);"와 같이 선언된 경우에는 void ShowInfo(const Point&);라는 함수원형 선언이 포함되어 있듯, friend 선언을 위해 별도의 함수원형 선언이 필요치는 않다.

 

 

C++에서 static

c언어에서 static

  • 전역변수에 선언된 static → 선언된 파일 내에서만 참조를 허용하겠다는 의미
  • 함수 내에 선언된 static → 한 번만 초기화되고, 지역변수와 달리 함수를 빠져나가도 소멸하지 않음

 

static 멤버변수(클래스 변수)

 static 멤버변수는 '클래스 변수'라고도 하며, 이는 일반적인 멤버변수와 달리 클래스당 하나씩만 생성되기 때문이다.

class Simple{
private:
	static int num;
public:
	Simple() {
    	num++;
    }
};

 위의 코드에 선언된 static 변수는 객체가 생성될 때마다 함께 생성되는 것이 아닌, 객체를 생성하건 생성하지 않건, 메모리 공간에 딱 하나만 할당이 되어서 공유되는 변수이다.

 예를 들어 아래와 같이 총 3개의 객체가 생성되면,

int main() {
	Simple simple1;
    Simple simple2;
    Simple simple3;
    ...
}

 세 개의 객체가 static 변수를 공유하게 된다. 또한 static 변수는 생성자에서 초기화하면 안되는데, 객체가 생성될 때 동시에 생성되는 변수가 아니고 이미 메모리 공간에 할당이 이루어진 변수기 때문에 객체가 0으로 초기화되기 때문이다.

  그리고 static 멤버가 위에서 처럼 private으로 선언되면, 해당 클래스의 객체들만 접근이 가능하지만, public으로 선언되면, 클래스의 이름 또는 객체의 이름을 통해 어디서든 접근이 가능하다.

 

 

static 멤버함수

 static 멤버함수 역시 그 특성이 static 멤버변수와 동일하므로 다음과 같은 특성들이 그대로 적용된다.

  • 선언된 클래스의 모든 객체가 공유한다.
  • public으로 선언이 되면, 클래스의 이름을 이용해서 호출이 가능하다.
  • 객체의 멤버로 존재하는 것이 아니다.

 여기서 객체의 멤버로 존재하지 않는다는 것 때문에 static 멤버함수에서 멤버변수에 접근하면 컴파일 에러가 발생한다.

이는 아래와 같이 이해가 가능하다.

  • 객체의 멤버가 아닌데, 어떻게 멤버변수에 접근을 할까?
  • 객체생성 이전에도 호출이 가능한데, 그럼 어떻게 멤버변수에 접근 할 수 있을까?
  • 멤버변수에 접근을 한다 쳐도, 어떤 객체의 멤버변수에 접근을 해야할까?

 이렇듯, static 멤버함수 내에서는 static으로 선언되지 않은 멤버변수의 접근도, 멤버함수의 호출도 불가능함을 알 수 있다.

즉, "static 멤버함수 내에서는 static 멤버변수와 static 멤버함수만 호출이 가능하다."

 

cont static 멤버

 클래스 내에 선언된 const 멤버변수(상수)의 초기화는 이니셜라이저를 통해서 해야만 했지만, const static으로 선언되는 멤버변수(상수)는 다음과 같이 선언과 동시에 초기화가 가능하다.

  • const static int num = 1;

 

키워드 mutable

 mutable 키워드를 통해 const 함수 내에서의 값의 변경을 예외적으로 허용할 수 도 있다.

class A{
private:
	int num1;
    mutable int num2; // const 함수에 대해 예외를 둔다