도순씨의 코딩일지

C++ :: const, friend 키워드 본문

𝐏𝐑𝐎𝐆𝐑𝐀𝐌𝐌𝐈𝐍𝐆/𝐂++

C++ :: const, friend 키워드

도순씨 2020. 8. 16. 12:00

🌼 const 객체

1
2
3
const int num = 10;
 
const SoSimple sim(20);
cs

 

변수를 상수화하듯 객체도 상수화 할 수 있습니다. 객체에 const 선언이 붙게 되면, 이 객체를 대상으로는 const 멤버 함수만 호출이 가능합니다. const 선언이 데이터 변경을 허용하지 않기 때문입니다.

 

예제를 통해서 const 객체의 특성을 확인해 봅시다.

 

⭐️ ConstObject.cpp

 

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
#include <iostream>
using namespace std;
 
class SoSimple{
private:
    int num;
public:
    SoSimple(int n) : num(n) {}
    SoSimple& AddNum(int n){
        num += n;
        return *this;
    }
    void ShowData() const{
        cout << "num: " << num << endl;
    }
};
 
int main(void){
    const SoSimple obj(7);
    //obj.AddNum(20);
    obj.ShowData();
    return 0;
}
cs

 

⭐️ ConstObject.cpp 실행 결과

 

1
num: 7
cs

 

const 형식의 객체이기 때문에 20번째 라인은 실행되지 않습니다. 

 

 

🌼 const와 함수 오버로딩

함수 오버로딩이 성립하기 위해서는 매개변수의 수나 자료형이 달라야 합니다. 더불어 const 선언 유무도 함수 오버로딩의 조건입니다.

 

1
2
void SimpleFunc() {....}
void SimpleFunc() const {....}
cs

 

다음 코드를 살펴보도록 합시다.

 

⭐️ ConstOverloading.cpp

 

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
#include <iostream>
using namespace std;
 
class SoSimple{
private:
    int num;
public:
    SoSimple(int n) : num(n) {}
 
    SoSimple& AddNum(int n){
        num += n;
        return *this;
    }
 
    void SimpleFunc(){
        cout << "SimpleFunc: " << num << endl;
    }
 
    void SimpleFunc() const{
        cout << "const SimpleFunc: " << num << endl;
    }
};
 
void YourFunc(const SoSimple &obj){
    obj.SimpleFunc();
}
 
int main(void){
    SoSimple obj1(2);
    const SoSimple obj2(7);
 
    obj1.SimpleFunc();
    obj2.SimpleFunc();
 
    YourFunc(obj1);
    YourFunc(obj2);
    return 0;
}
cs

 

⭐️ ConstOverloading.cpp 실행결과

 

1
2
3
4
SimpleFunc: 2
const SimpleFunc: 7
const SimpleFunc: 2
const SimpleFunc: 7
cs

 

오버로딩된 const 함수를 호출할 수 있다.

 

 

🌼  friend 선언

friend 선언은 다음과 같이 정리할 수 있습니다.

 

💡 A 클래스와 B 클래스를 대상으로 friend 선언을 하면, B클래스는 A 클래스의 private 멤버에 직접 접근이 가능하다.

💡 A 클래스도 B 클래스의 private 멤버에 접근 가능하려면 B 클래스가 A 클래스를 대상으로 friend 선언을 해야 한다.

 

friend 선언을 하고 있는 클래스를 살펴봅시다.

 

⭐️ MyFriendClass.cpp

 

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
#include <iostream>
#include <cstring>
using namespace std;
 
class Girl;
 
class Boy{
private:
    int height;         // 키
    friend class Girl;  // Girl 클래스를 friend로 선언
public:
    Boy(int len) : height(len){}
    void ShowYourFriendInfo(Girl &frn);
};
 
class Girl{
private:
    char phNum[20];
public:
    Girl(char * num){
        strcpy(phNum, num);
    }
    void ShowYourFriendInfo(Boy &frn);
    friend class Boy;   // Boy 클래스에 대한 friend 선언
};
 
void Boy::ShowYourFriendInfo(Girl &frn) {
    cout << "Her phone number: " << frn.phNum << endl;
}
 
void Girl::ShowYourFriendInfo(Boy &frn) {
    cout << "His height: " << frn.height << endl;
}
 
int main(void){
    Boy boy(170);
    Girl girl("010-1234-5678");
    boy.ShowYourFriendInfo(girl);
    girl.ShowYourFriendInfo(boy);
    return 0;
}
cs

 

⭐️ MyFriendClass.cpp 실행 결과

 

1
2
Her phone number: 010-1234-5678
His height: 17
cs

 

friend는 정보 은닉을 망가지게 만들기 때문에 소극적으로 사용해야 합니다. 클래스의 멤버 함수, 전역함수로도 friend 선언이 가능합니다. 다음 예제를 살펴보도록 합시다.

 

⭐️ MyFriendFunction.cpp

 

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
#include <iostream>
using namespace std;
 
class Point;    // Point가 클래스 이름임을 선언
 
class PointOP{
private:
    int opcnt;
public:
    PointOP() : opcnt(0){}
 
    Point PointAdd(const Point&const Point&);
    Point PointSub(const Point&const Point&);
    ~PointOP(){
        cout << "Operation times: " << opcnt<<endl;
    }
};
 
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 Point PointOP::PointSub(const Point &const Point &);
    friend void ShowPointPos(const Point&);
};
 
Point PointOP::PointAdd(const Point& pnt1, const Point& pnt2){
    opcnt ++;
    return Point(pnt1.y+pnt2.x, pnt1.y + pnt2.y);
}
 
Point PointOP::PointSub(const Point &pnt1, const Point &pnt2) {
    opcnt++;
    return Point(pnt1.x - pnt2.x, pnt1.y-pnt2.y);
}
 
int main(void){
    Point pos1(12);
    Point pos2(24);
    PointOP op;
 
    ShowPointPos(op.PointAdd(pos1, pos2));
    ShowPointPos(op.PointSub(pos2, pos1));
    return 0;
}
 
void ShowPointPos(const Point& pos){
    cout << "x: " << pos.x << ", ";
    cout << "y: " << pos.y << endl;
}
cs

 

⭐️ MyFriendFunction.cpp 실행결과

 

1
2
3
x: 4, y: 6
x: 1, y: 2
Operation times: 2
cs

 

 

🌼 C++의 static 

C언어에서의 static은 C++에서도 통용됩니다. 전역변수에 선언된 static의 의미는 선언된 파일 내에서만 참조를 허용하겠다는 의미입니다. 함수 내의 선언된 static의 의미는 한 번만 초기화되고, 지역변수와 달리 함수를 빠져나가도 소멸되지 않습니다

 

 

 

 

📜 출처

윤성우(2010). 윤성우 열혈 C++ 프로그래밍. 오렌지미디어.

 

Comments