1] Const
1. 객체의 상수화
: C++ 에서는 변수에 const를 붙이는것 이외에 객체에도 const를 붙일 수 있다. 

const SoSimple sim(20);

이렇게 객체에 const가 붙게 되면, 이 객체를 대상으로는 const 멤버함수만 호출이 가능하다. 
즉, 이 객체의 데이터 변경을 허용하지 않는다. 

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

void SimpleFunc() { ... }
void SimpleFunc() const { ... }

즉, const로 선언된 객체가 함수를 호출하면 const 함수가 불리고 일반 객체가 함수를 호출하면 일반 함수가 호출된다. 

2] 클래스와 함수에 대한 friend 선언
1. 클래스의 friend 선언
: friend 선언은 private 멤버의 접근을 허용하는 선언이다. 

class Girl; // Girl 이라는 이름이 클래스의 이름임을 알림

class Boy
{
private:
    int height;
    friend class Girl;  // 사실 위에 class  Girl; 문장이 없어도 된다. 이 문장은 Girl이 클래스라는 사실과 Girl 클래스가 friend 라는 사실을 동시에 알려준다. 
};

class Girl
{
private:
    char phNum[20];
public:
    Girl(char* num)
    {
        strcpy(phNum, num);
    }
    
    void ShowYourFriendInfo(Boy &frn)
    {
        cout << "His height: "<<frn.height << endl;
    }
};

Boy 클래스가 Gril 클래스를 Friend 선언했다. 그래서 Girl 클래스는 Boy 클래스의 private 멤버의 접근이 가능하다. 그 반대는 안된다. 

* friend 선언은 얽히고 설킨 클래스의 관계를 friend로 풀려는 사람들을 종종 볼수 있다. 이 방법은 friend 사용의 잘못된 예이다. 정보의 은닉성을 훼손하는 행위이기 때문이다. friend 사용은 최대한 소극적으로 하는게 맞다. 다만, 이후에 배울 연산자 오버로딩에서 효율적으로 friend를 사용하는 방법을 배울것이다. 

2. 함수의 friend 선언
: 전역함수를 대상으로도, 클래스 멤버함수를 대상으로도 friend 선언이 가능하다. 

class Point;

class PointOP
{
private:
    int opcnt;
public:
    PointOP() : opcnt(0) {  }
    
    Point PointAdd(const Point&, const Point&);
};

class Point
{
private:
    int x;
    int y;
public:
    Point(const int &xpos, const int &ypos) : x(xpos), y(ypos) {  }
   
    friend Point PointOP::PointAdd(const Point&, const Point&);
    friend void ShowPointPos(const Point&);
};

Point PointOP::PointAdd(const Point& pnt1, const Point& pnt2)
{    
    opcnt++;
    return Point(pnt1.x+pnt2.x, pnt1.y+pnt2.y);
}

void ShowPointPos(const Point& pos)
{
    cout<<"x: "<<pos.x<<endl;
    cout<<"y: "<<pos.y<<endl;
}

위 코드에서 Point클래스에서 PointOP 클래스의 PointAdd 멤버함수를 friend 선언했기 때문에, PointAdd 멤버함수 에서는 Point의 private 멤버의 접근이 가능하다. 
또한 Point클래스에서 ShowPointPos() 전역 함수도 friend 선언했기 때문에 ShowPointPos() 전역함수에서도 Point 클래스의 private 멤버의 접근이 가능하다.

그리고 Point 클래스에서 friend void ShowPointPos(const Point&); 선언은 friend 선언 이외에 함수 원형 선언의 의미도 포함되어 있어서 따로 함수 원형 선언을 할 필요가 없다. 


3] C++ 에서의 static 
1. C언어에서 이야기한 static
- static 전역변수 
: 선언된 파일 내에서만 참조를 허용하겠다는 의미
- 함수 내에 선언된 static 의미
: 한번만 초기화되고, 지역변수와 달리 함수를 빠져나가도 소멸되지 않는다. 

2. static 멤버 변수
: 멤버 변수를 static 으로 선언하면, 해당 변수는 instance 마다 하나씩 존재하는 변수가 아니라 클래스에 하나만 존재하는 변수이고, 모든 instance가 해당 변수를 공유한다. 

class SoSimple
{
private:    
    static int simObjCnt;
public:
    SoSimple()
    {
        simObjCnt++;
    }    
};

int SoSimple::simObjCnt = 0;

위 코드에서 simObjCnt는 static 멤버변수이다. instance가 생성될 때 마다 값이 1 증가할 것이다. 
int SoSimple::simObjCnt = 0; 는 static 멤버변수를 초기화 할때의 문법이다. 풀어서 해석하면 "simObjCnt가 메모리 공간에 할당될때 0으로 초기화 해줘라" 라는 뜻이다.

3. static 멤버변수의 또 다른 접근방법
: static 멤버변수는 public으로 선언되기만 하면 어디서든 접근이 가능한 변수다.
위 SoSimple 클래스에서 simObjCnt가 public으로 선언되어 있으면 아래와 같은 문법으로 접근이 가능하다. 

SoSimple sim;

SoSimple.simObjCnt;
sim.simObjCnt; // 이 문법은 인스턴스 멤버변수에 접근하는것과 같은 착각을 일으킨다. 가급적 클래스 이름으로 접근하는 방법을 택하자. 

4. static 멤버 함수
: 개념은 static 멤버 변수와 같다. 단지 변수가 함수로 바뀌었을 뿐이다. 그리고 static 멤버 함수 안에서는 인스턴스 멤버변수에 접근할 수 없다. 
즉, static 멤버 함수 안에서는 static 멤버 변수와 static 멤버 함수만 호출이 가능하다. 

5. const static 멤버
: 이전에 배웠듯이 const 멤버변수(상수)는 이니셜라이저를 통해서만 초기화할 수 있었다. 그러나 const static으로 선언되는 멤버변수는 다음과 같이 선언과 동시에 초기화가 가능하다. 

class CountryArea
{
public:
    const static int RUSSIA = 1707540;
    const static int CANADA = 998467;
};

6. 키워드 mutable
: "mutable" 키워드의 의미는 "const 함수 내에서의 값의 변경을 에외적으로 허용한다." 이다. 설명만 들어도 가급적 사용하면 안될것 같은 느낌이 든다.

class SoSimple
{
private:
    mutable int num2;
public:
    void setNum2(int num) const
    {
        num2 = num;
    }
};

위 코드와 같이 setNum2() 는 const 멤버함수로 선언되어 있는데도 불구하고 num2 멤버 변수가 mutable 선언되어 있기 때문에 const 멤버함수에서 예외적으로 값 변경이 가능하다. 



'C++' 카테고리의 다른 글

[C++] 상속과 다형성  (0) 2017.12.25
[C++] 상속  (0) 2017.12.25
[C++] 복사 생성자(Copy Constructor)  (0) 2017.12.23
[C++] 클래스의 완성  (1) 2017.12.23
[C++] 클래스의 기본  (0) 2017.12.23
Posted by 홍성곤
,