'C, C++'에 해당되는 글 21건

  1. 2018.10.19 C++ 가상 함수(Virtual Function) 8
  2. 2018.10.12 C++ 연산자 오버로딩 2
  3. 2018.10.11 C++ 함수 오버로딩
  4. 2018.10.11 C/C++ 메모리 동적할당
  5. 2018.10.10 C++ friend 클래스와 함수 1



안녕하세요 열코입니다.

이번 시간에는 C++ 클래스의 가상 함수(Virtual Function)에 대해 알아보도록 하겠습니다.

가상 함수는 기본 클래스(상속되지 않은 클래스) 내에서 선언되어 파생 클래스에 의해 재정의되는 맴버 함수입니다.

포인터(Pointer) 또는 기본 클래스에 대한 참조(Reference)를 사용하여 파생 클래스의 객체를 참조하면 해당 객체에 대해

가상 함수를 호출하고 파생 클래스의 함수를 실행할 수 있습니다.

이는 주로 실행시간(Runtime)에 함수의 다형성(Polymorphism)을 구현하는데 사용됩니다.

가상 함수는 기본 클래스내에 virtual 키워드로 함수를 선언합니다.


가상 함수 선언에는 몇가지 규칙이 존재합니다.

1. 클래스의 공개(public) 섹션에 선언합니다.

2. 가상 함수는 정적(static)일 수 없으며 다른 클래스의 친구(friend) 함수가 될 수도 없습니다.

3. 가상 함수는 실행시간 다형성을 얻기위해 기본 클래스의 포인터 또는 참조를 통해 접근(access)해야 합니다.

4. 가상 함수의 프로토타입(반환형과 매개변수)은 기본 클래스와 파생 클래스에서 동일합니다.

5. 클래스는 가상 소멸자를 가질 수 있지만 가상 생성자를 가질 수 없습니다.


다음 예제 소스코드가 어떻게 실행될 지 예상해보세요.


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
#include <iostream>
 
using namespace std;
 
class parent {
public :
    virtual void v_print() {
        cout << "parent" << "\n";
    }
    void print() {
        cout << "parent" << "\n";
    }
};
 
class child : public parent {
public :
    void v_print() {
        cout << "child" << "\n";
    }
    void print() {
        cout << "child" << "\n";
    }
};
 
int main() {
    parent* p;
    child c;
    p = &c;
 
    p->v_print();
    p->print();
 
    return 0;
}
cs


parent 클래스를 가리키는 포인터 p를 선언하고, child 클래스의 객체 c를 선언했습니다.

이 포인터 p는 c객체를 가리킵니다.

몸체는 parent 클래스지만 실제 객체는 child 클래스입니다.

이 포인터 p를 이용하여 가상 함수인 v_print()와 오버라이딩 된 함수 print()를 출력하면 각각의 함수는

어느 클래스에서 호출될까요? 답은 아래와 같습니다.



실행 결과


child

parent


v_print() 함수는 가상 키워드로 선언되어 가상 함수가 되었으며

가상 함수는 실행시간(런타임)에 그 값이 결정됩니다. (후기 바인딩이라고도 합니다.)

포인터 p에는 child 클래스의 객체가 들어가 있고 포인터가 가리키는 위치에 따라 child 클래스의 v_print() 함수가 호출되었으며

일반 함수인 print()는 컴파일 시간에 이미 결정되기 때문에 31번째 줄에 p에서 print() 함수를 호출할 때

parent 클래스의 print() 함수가 호출되는것으로 결정이 끝나버린 상태입니다.

따라서 parent 클래스의 print() 함수가 호출되게 됩니다.


또한 아래의 예제 소스코드를 보며 주의사항에 대해 설명하겠습니다.


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 parent {
public :
    void print1() {
        cout << "parent print1" << "\n";
    }
    virtual void print2() {
        cout << "parent print2" << "\n";
    }
    virtual void print3() {
        cout << "parent print3" << "\n";
    }
};
 
class child : public parent {
public :
    void print2() {
        cout << "child print2" << "\n";
    }
    void print3(int x) {
        cout << "child print3" << "\n";
    }
};
 
int main() {
    parent* p;
    child c;
    p = &c;
 
    p->print1();
    p->print2();
    p->print3();    
 
    return 0;
}
cs


위 예제 코드를 보시면 parent 클래스에서 print1() 함수는 일반 함수로 선언되었으며,

print2(), print3() 함수는 virtual 키워드를 통해 가상 함수로 선언되었습니다.

또한 상속받은 child 클래스에서 print3() 함수는 오버라이딩하여 매개변수를 추가했습니다.

똑같이 parent 클래스의 포인터를 선언하여 파생 클래스인 child 클래스의 객체를 참조하고 포인터를 통해

print1(), print2(), print3() 함수를 호출하면 어떤 결과가 도출될까요?


실행 결과


parent print1

child print2

parent print3


print1() 함수는 일반 함수이기 때문에 컴파일 시간에 결정이 나고 parent 클래스의 print1() 함수가 호출됩니다.

print2() 함수는 가상 함수이기 때문에 실행 시간에 결정이 됩니다. parent 클래스지만 가리키고있는 객체가 child 클래스이기 때문에

child 클래스의 print2() 함수가 호출되게 됩니다.

print3() 함수는 가상 함수이지만 child 클래스에서는 매개변수가 없는 함수를 호출했기 때문에 부모 클래스인 parent 클래스의

print3() 함수가 호출되게 된 것입니다.



이상 'C++ 가상 함수'에 대해 알아보았습니다.

질문 또는 오타나 잘못된 정보가 있는 경우 댓글로 달아주세요!

공감♡ 버튼을 눌러주시면 더욱 유용하고 좋은 포스팅으로 찾아 뵙겠습니다.




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

C 정적(static) 변수  (0) 2018.10.29
C 변수 선언 및 키워드  (0) 2018.10.25
C 표준 입력 함수 scanf  (0) 2018.10.23
C 표준 출력 함수 printf()  (0) 2018.10.22
C++ 연산자 오버로딩  (2) 2018.10.12
C++ 함수 오버로딩  (0) 2018.10.11
C/C++ 메모리 동적할당  (0) 2018.10.11
C++ friend 클래스와 함수  (1) 2018.10.10

C++ 연산자 오버로딩




안녕하세요 열코입니다.

저번시간에 함수 오버로딩에 대해 알아보았는데요.

이번시간에는 연산자 오버로딩에 대해 알아보도록 하겠습니다.


☞ 연산자 오버로딩이란

기존의 제공하고 있는 연산자를 재정의하여 사용자 정의 클래스로 사용하는 것을 말합니다.

대부분의 기본 제공 연산자 함수는 전역 함수 또는 클래스로 재정의 가능합니다.

오버로드 된 연산자는 함수로 구현됩니다.



☞ 연산자 오버로드에 대한 일반 규칙

  • **과 같은 새로운 연산자를 정의할 수는 없습니다.

  • 기본 제공 데이터 형식에 적용할 때 연산자의 의미를 다시 정의 할 수 없습니다.

  • 오버로드 된 연산자는 비정적(non-static) 클래스 멤버 함수거나 전역 함수이어야 합니다.

   (private 또는 protected 접근자의 전역 함수는 해당 클래스의 friend로 선언해야 합니다.)
  • 단항 연산자 또는 이항 연산자(&, *, +, -)로 오버로드 가능하며 각 사용을 별도로 오버로드 할 수 있습니다.

  • 멤버 함수로 오버로드된 연산자의 첫번째 파라미터는 항상 연산자가 호출되는 객체의 클래스 형식입니다.

   (첫번째 파라미터에 대한 변환은 제공되지 않습니다.)




 오버로딩 불가능한 연산자

아래 표의 연산자들은 오버로드 할 수 없습니다.


 연산자

이름 

멤버선택 

.* 

멤버 포인터 선택 

:: 

범위 

?: 

조건 

문자열 전처리기 변환 

## 

전처리기 연결 



 간단한 예


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
#include <iostream>
using namespace std;
 
class Point {
private :
    int x, y;
 
public :
    Point(int x_, int y_) {
        x = x_;
        y = y_;
    }
 
    void print() {
        cout << "x : " << x << ", y : " << y << "\n";
    }
};
 
 
int main(void) {
    Point p1 = { 11 };
    Point p2(22);
    
    Point p3 = p1 + p2;
 
    p3.print();
 
    return 0;
}
cs

다음과 같이 Point라는 클래스가 있고 Point 클래스 내부에는 int x와 int y가 있습니다.
main함수에서 Point 객체인 p1과 p2를 생성해주고, p3에는 p1과 p2를 더한값을 저장하고 싶습니다.
근데 + 연산자에 대해 Point 객체의 덧셈은 지원 해주지 않습니다.
Point 클래스는 방금 제가 임의로 만든 클래스이며, + 연산자가 무엇을 의미하는지 모르기 때문이죠.
마치 String 변수의 + 연산이 a+a = aa인지 a+a=b인지 모르는것 처럼요.


이를 해결하기 위해 C++에서는 연산자 오버로딩을 제공합니다.
설명은 위에서 해드렸으니 코드에 대해 설명하겠습니다.
먼저 Point 클래스의 + 연산자에 대한 오버로딩 예제 코드입니다.

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
#include <iostream>
using namespace std;
 
class Point {
private :
    int x, y;
 
public :
    Point(int x_, int y_) {
        x = x_;
        y = y_;
    }
 
    void print() {
        cout << "x : " << x << ", y : " << y << "\n";
    }
 
    Point operator + (Point& p) {
        x = x + p.x;
        y = y + p.y;
        return Point(x, y);
    }
};
 
 
int main(void) {
    Point p1 = { 11 };
    Point p2(22);
    
    Point p3 = p1 + p2;
 
    p3.print();
 
    return 0;
}
cs

18번째 줄을 보시면 새로운 함수가 하나 생성되었습니다.
+ 연산자에 대한 오버로딩 함수인데요. 하나씩 살펴보겠습니다. ^^
반환형으로는 Point 객체네요. 
함수의 이름은 operator입니다. 함수의 이름을 operator로 사용함으로써 컴파일러에게 연산자 오버로드 함수인것을 명시합니다.
뒤에 연산자 +를 입력했습니다. 매개변수로는 Point 객체의 참조변수입니다.

30번째 줄을 보시면 Point p3 = p1 + p2; 라는 코드가 있습니다.
여기서 p1이 오버로드 된 + 연산자 함수를 호출했으며, + 뒤에있는 p2는 Point& p로 넘겨 받아지는 것 입니다.
반환값은 Point 객체로 x와 y가 각각 더해진 새로운 임시 Point 객체를 반환합니다.
이 반환된 임시 객체 값이 p3 값으로 넘어가서 결과적으로 3, 3이 출력되는 것입니다.

ㅇ 출력 결과

x : 3, y : 3


☞ 연산자 오버로딩 활용 1
데이터 타입 변환에 대한 연산자 또한 오버로딩 할 수 있습니다.
다음 예제를 확인해보세요.

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
#include <iostream>
using namespace std;
 
class DIV {
private :
    int num, div;
public :
    DIV(int n, int d) {
        num = n;
        div = d;
    }
 
    operator double() const {
        return double(num) / double(div);
    }
};
 
 
int main(void) {
    DIV d(13);
    double db = d;
    cout << d;
 
    return 0;
}
cs

21번째 줄을 보시면 double 변수로 db를 선언하고 값을 DIV 객체인 d를 넘겨주었습니다.
어떻게 이게 가능할까요?
13번째 줄을 보시면 double 이라는 키워드를 연산자 오버로딩하여 double 값을 반환하는 함수로 오버로딩 했습니다.
그러므로 double 변수에 대입할 수 있게 된 것이죠.

☞ 연산자 오버로딩 활용 2
cin, cout의 << 연산자, >> 연산자 오버로딩 역시 가능합니다.
다음 예제 코드는 cin 의 << 연산자에 대한 오버로딩 입니다.

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
#include <iostream>
using namespace std;
 
class Point {
private :
    int x, y;
 
public :
    Point(int x_, int y_) {
        x = x_;
        y = y_;
    }
 
    friend ostream& operator<<(ostream&const Point&);
};
 
ostream& operator<<(ostream& os, const Point& p) {
    os << p.x << ", " << p.y;
    return os;
}
 
int main(void) {
    Point p(23);
    
    cout << p;
 
    return 0;
}
cs

Point라는 클래스가 있습니다. p 라는 객체를 생성하고 cout << p; 라는 코드는 분명 오류가 발생합니다.
왜나면 cout의 << 연산자는 기본적으로 사용자 정의 클래스에 대한 출력을 지원해 주지 않기 때문이죠.
이를 연산자 오버로딩을 통해 해결 가능합니다.
17번째 줄을 보시면 << 연산자에 대한 오버로드 함수입니다.
또한 Point 객체의 private 멤버인 x와 y에 접근 할 수 있도록 Point 클래스 내부에 friend 함수를 지정해 주었습니다.

ㅇ 출력 결과

2, 3



이상 '연산자 오버로딩'에 대해 알아보았습니다.

질문 또는 오타나 잘못된 정보가 있는 경우 댓글로 달아주세요!

공감♡ 버튼을 눌러주시면 더욱 유용하고 좋은 포스팅으로 찾아 뵙겠습니다.



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

C 변수 선언 및 키워드  (0) 2018.10.25
C 표준 입력 함수 scanf  (0) 2018.10.23
C 표준 출력 함수 printf()  (0) 2018.10.22
C++ 가상 함수(Virtual Function)  (8) 2018.10.19
C++ 함수 오버로딩  (0) 2018.10.11
C/C++ 메모리 동적할당  (0) 2018.10.11
C++ friend 클래스와 함수  (1) 2018.10.10
C++ 클래스 접근제한자  (0) 2018.10.10

C++ 함수 오버로딩




안녕하세요 열코입니다.

이번시간에는 C++ 에서 함수 오버로딩에 대해 알아보겠습니다.


☞ 함수 오버로딩이란?

같은 함수의 이름을 가지고 있지만 파라미터(매개변수) 및 리턴 타입 등의 특징이 다른 여러개의 함수를 만드는 것입니다.

예를들어 우리가 C++ 프로그래밍을 할 때에 cout 출력 함수를 통해 int, char, string, double 등의 여러가지 타입의 자료형을

다른 함수가 아닌 cout 하나의 함수를 통해 출력할 수 있는 기능을 구현하는데 사용됩니다.


* 너무 많이 함수를 오버로딩 할 경우 코드가 복잡해지며 어떤 오버로드 함수가 호출되었는지 알기 힘들어지므로

적절한 상황에 적당히 사용하는것을 권합니다.


 함수 오버로딩 예제


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
#include <iostream>
using namespace std;
 
int yc(int i) {
    return i + 1;
}
char yc(char c) {
    return c + 1;
}
double yc(double d) {
    return d + 1.1;
}
 
 
int main(void) {
    int x = 5;
    char y = 'a';
    double z = 3.3;
 
    cout << yc(x) << "\n";
    cout << yc(y) << "\n";
    cout << yc(z) << "\n";
 
    return 0;
}
cs


위의 코드처럼 같은 이름을 가진 함수가 여러개 존재합니다.

main 함수에서는 yc() 라는 함수를 호출할 뿐이고 매개변수로 int, char, double 형식이 순서대로 들어갑니다.

컴파일러는 매개변수를 구분하여 어떤 함수를 호출할 지 결정합니다.


ㅇ 출력 결과


6

b

4.4



 함수 오버로딩이 가능하지 않은 경우?

Microsoft MSDN에서는 함수 오버로드 고려사항으로 다음과 같이 정의합니다.


출처 : https://msdn.microsoft.com/ko-kr/library/5dhe1hce.aspx



C++에서 함수 오버로딩을 할 수 없는 함수들을 하나씩 살펴보도록 하겠습니다.


1. 반환 값의 형식만 다른 함수 선언.


1
2
3
4
5
6
7
8
int yc() {
    return 1;
}
 
char yc() {
    return 'c';
}
 
cs


위와 같이 반환 값의 형식만 다른 함수를 오버로드 할 경우 다음과 같은 컴파일 오류가 발생합니다.


- 반환 형식으로만 구분되는 함수를 오버로드할 수 없습니다.

- 'char yc(void)': 오버로드된 함수가 'int yc(void)'과(와) 반환 형식만 다릅니다.

- 'yc': 재정의. 기본 형식이 다릅니다.



2. 형식이 같은 static(정적) 멤버 함수를 오버로드하는 경우.


1
2
3
4
5
6
class YC {
    static void yc(int i) {}
 
    void yc(int i) {}
};
 
cs


위와 같이 반환 값 형식과 매개변수 형식이 같은 정적 메소드와 비 정적 메소드를 오버로드할 수 없습니다.

다음과 같은 컴파일 오류가 발생합니다.


- 매개 변수 형식이 같은 정적 및 비정적 멤버 함수를 오버로드할 수 없습니다.



3. 매개변수 형식이 배열과 포인터


1
2
int yc(int *p);
int yc(int p[]);
cs


위와 같이 함수 몸체가 없이 정의만 하는 경우 컴파일 오류는 발생하지 않지만, 컴파일러가 동일한 함수로 인지합니다.

매개변수 배열 선언은 포인터 선언으로 조정되기 때문에 단순히 위의 함수를 재정의 하는 구문입니다.


아래 코드의 경우도 마찬가지로 동일한 함수를 재정의하는 구문입니다.


1
2
3
int yc(int );
int yc(int *);
 
cs


매개변수에 const로 구분을 짓는것 또한 마찬가지입니다.


1
2
3
4
5
6
int yc(int x) {
    return x;
}
int yc(const int x) {
    return x;
}
cs


위와 같이 함수를 선언한 경우에는 컴파일 에러를 발생시킵니다.


- 'int yc(int)' 함수에 이미 본문이 있습니다.


위의 케이스들은 함수 오버로딩이 아닌 단순 함수 재정의라고 볼 수 있습니다.



이상 'C++ 함수 오버로딩'에 대해 알아보았습니다.

질문 또는 오타나 잘못된 정보가 있는 경우 댓글로 달아주세요!

공감♡ 버튼을 눌러주시면 더욱 유용하고 좋은 포스팅으로 찾아 뵙겠습니다.



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

C 표준 입력 함수 scanf  (0) 2018.10.23
C 표준 출력 함수 printf()  (0) 2018.10.22
C++ 가상 함수(Virtual Function)  (8) 2018.10.19
C++ 연산자 오버로딩  (2) 2018.10.12
C/C++ 메모리 동적할당  (0) 2018.10.11
C++ friend 클래스와 함수  (1) 2018.10.10
C++ 클래스 접근제한자  (0) 2018.10.10
C++ 클래스와 객체  (0) 2018.10.09

C/C++ 메모리 동적할당




안녕하세요 열코입니다.

이번시간에는 C/C++에서의 메모리 동적할당에 대해 알아보도록 하겠습니다.



☞ 메모리 동적 할당이란?

C/C++에서 실행 시간동안 사용할 메모리 공간을 할당하는 것을 말합니다.

메모리 공간 필요 시 할당하고, 사용이 끝난 후 반납을 사용자가 원하는 시점에 원하는 크기만큼 가능합니다.

사용자에 의해 메모리가 동적으로 할당이 되면 프로그램이 끝날 때 까지 유지되므로,

메모리 공간 사용이 끝나면 메모리 낭비(누수)를 줄이기 위해 명시적으로 메모리 할당을 해제 해주어야합니다.


* 참고로 자바에는 가비지 컬렉션이 존재하여 사용되지않는 메모리를 자동으로 해제해줍니다.

C/C++에는 가비지 컬렉션이 존재하지 않으므로 사용자가 명시적으로 메모리를 해제 해 주어야 합니다. 



 컴퓨터 메모리 구조?

컴퓨터 메모리 구조에 대해 잠깐 짚고 넘어가겠습니다. 컴퓨터 메모리의 공간은 

크게 4부분 - 스택, 힙, 데이터, 코드(텍스트) 부분으로 나눌 수 있습니다.


여기서 스택, 힙 공간은 프로그램 실행(런타임) 크기가 결정됩니다.

데이터와 코드 부분은 컴파일러에 의해 컴파일시 크기가 결정됩니다.


- 스택(Stack) 공간은 지역변수와 매개변수 등이 할당되는 임시적인 영역입니다.

- 힙(Heap) 공간은 동적으로 메모리를 할당하는 곳이며 생성 중 크기를 결정합니다.

- 데이터(Data) 공간은 전역 변수와, 정적(static) 변수, 초기화 된 배열 등이 존재합니다.

- 코드(Code) 공간은 프로그램의 명령어나 기계어 명령이 존재합니다. 



 동적 메모리 할당/해제 방법?

C 프로그래밍에서는 malloc()과 calloc() 함수 등을 사용하여 런타임에 메모리를 동적으로 생성하며,

free() 함수를 사용하여 동적으로 할당된 메모리를 명시적으로 해제합니다.

C++ 프로그래밍에서는 이러한 함수들을 더 편하게 사용할 수 있도록 new와 delete 연산자를 사용하여 할당 및 해제합니다.


동적할당 코드에는 포인터 개념 및 사용이 포함되어 있습니다. 

아직 포인터에 대한 개념이 잡혀있지 않다면 여기를 눌러 개념을 잡고 넘어 갑시다.


- C 예제코드


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
#include <stdio.h>
#include <stdlib.h>
 
int main(void) {
    int *p;
    int size = 5;
    p = (int *)malloc(sizeof(int* 5);
 
    for (int i = 0; i < 5; i++) {
        p[i] = i + 1;
    }
 
    for (int i = 0; i < 5; i++) {
        printf("%d\n", p[i]);
    }
 
    free(p);
 
    return 0;
}
cs


먼저 malloc() 함수를 사용하기 위해 stdlib.h 헤더파일을 include 해줍니다.

그리고 malloc() 함수를 사용하기 위해 포인터 변수를 하나 생성합니다. 여기서 포인터의 자료형을 동적할당 하려는 자료형과

일치해야 합니다. 저는 int형 변수 5개를 동적할당 받기위해 int형 포인터 변수를 선언했습니다.


그리고 malloc() 함수의 반환값은 void*이므로 (int*)를 malloc() 함수 앞에 명시적으로 형변환을 시켜줍니다.

만약 char*라면 (char*)를 사용하여 명시적으로 형변환을 해줍니다. (자료형에 맞추시면 됩니다.)


그리고 malloc() 함수의 매개변수로 동적할당 받을 메모리 크기를 넘겨줍니다.

int형 변수 5개이므로 4*5 = 20을 넘겨주면 되겠다 싶더니 무슨 이상한 문자들이 있군요...

sizeof() 함수는 해당 자료형의 크기를 반환합니다. sizeof(int)니까 int형 자료형의 크기가 되겠군요.

5개가 필요하니 5로 초기화 해준 size를 곱해줍니다.

여기서 sizeof()의 사용을 한 이유는 프로그램 사용자마다 운영체제가 다르기 때문에 자료형의 크기가 달라질 수 있기 때문입니다.

sizeof()함수를 사용하면 64bit 컴퓨터에서는 8바이트로 반환되기 때문이죠.


그리고 동적할당 받은 메모리는 배열처럼 사용 가능합니다. (보통 배열의 동적 크기를 지정해주기 위해 사용됩니다.)


사용후에는 free() 함수를 이용하여 메모리 할당을 해제 해 주었습니다. 


ㅇ 출력 결과


1

2

3

4

5



- C++ 예제코드

C++ 프로그래밍에서는 new와 delete 키워드를 사용합니다.

사용법은 C 프로그래밍 보다 훨씬 쉬우니 설명은 생략하고 아래의 예제 코드를 확인 해 봅시다.


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
#include <iostream>
using namespace std;
 
int main(void) {
    int *= new int[5];
 
    for (int i = 0; i < 5; i++) {
        p[i] = i + 1;
    }
 
    for (int i = 0; i < 5; i++) {
        cout << p[i] << "\n";
    }
 
    delete[] p;
 
    return 0;
}
cs


어때요? 진짜 말한대로 코드가 간단하죠?

new 키워드를 통해 int형 변수 5개 ([5])를 동적할당합니다.

그리고 delete키워드를 통해 동적할당 해제.


ㅇ 출력 결과


1

2

3

4

5


개인적으로 C++ 프로그래밍의 메모리 동적 할당 방법이 더 쉽고 간결해서 자주 사용하는 편입니다. ^^



이상 'C/C++ 메모리 동적할당'에 대해 알아보았습니다.

질문 또는 오타나 잘못된 정보가 있는 경우 댓글로 달아주세요!

공감♡ 버튼을 눌러주시면 더욱 유용하고 좋은 포스팅으로 찾아 뵙겠습니다.



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

C 표준 출력 함수 printf()  (0) 2018.10.22
C++ 가상 함수(Virtual Function)  (8) 2018.10.19
C++ 연산자 오버로딩  (2) 2018.10.12
C++ 함수 오버로딩  (0) 2018.10.11
C++ friend 클래스와 함수  (1) 2018.10.10
C++ 클래스 접근제한자  (0) 2018.10.10
C++ 클래스와 객체  (0) 2018.10.09
C/C++ 구조체 사용법 및 예제  (1) 2018.10.08



안녕하세요 열코입니다.

저번시간에 C++ 클래스와 접근제한자에 대해 알아보았는데요.

이번에는 저번시간 protected 제한자 부분에서 언급했던 friend(친구) 클래스와 함수에 대해 알아보겠습니다.


☞ freind 클래스란?

firend 클래스는 friend로 선언된 다른 클래스의 private 및 protected 멤버에 접근할 수 있습니다.

특정 상황에서 클래스 내에 접근하지 못하도록 private 제한을 두었는데, 필요의 경우 해당 클래스나 함수에서

접근 가능하도록 사용하는것이 friend 클래스 및 함수입니다.

사용법은 friend 키워드를 사용하여 클래스나 함수를 명시 해 주는 것 인데요.

아래 예제는 friend 클래스를 지정해주는 예제코드입니다.


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
#include <iostream>
#include <string>
using namespace std;
 
class Friend1 {
private :
    string name;
 
    friend class Friend2;
};
 
class Friend2{
public : 
    void set_name(Friend1& f, string s) {
        f.name = s;
    }
    void show_name(Friend1& f) {
        cout << f.name << "\n";
    }
};
 
int main(void) {
    Friend1 f1;
    Friend2 f2;
    
    f2.set_name(f1, "열코");
    f2.show_name(f1);
 
    return 0;
}
cs


위 클래스를 보시면 Friend1 클래스와 Friend2 클래스가 있습니다.

Friend1 클래스에는 private 멤버 변수로 name이라는 string 변수가 존재합니다.

그 아래 보시면 friend class Friend2; 라는 코드가 보입니다.

이 코드가 바로 "나(Friend1)는 Friend2의 친구니까 내 개인적인 정보를 공유 해도 돼!" 라는 뜻입니다.

그리고 Friend2 클래스의 코드를 보시면 public 제한자의 함수 두개가 보입니다.



setter 함수와 출력 함수인데요, Friend1의 private 멤버인 name에 직접 접근하는것을 볼 수 있습니다.

친구니까 개인적인거 정도는 허용가능하겠죠? 

이런식으로 private 멤버나 protected 멤버를 외부 클래스에서 접근할 수 있도록 하는것이 friend 키워드입니다.


ㅇ 출력 결과


열코


☞ friend 함수란?

friend 클래스와 마찬가지로 private 및 protected 멤버에 접근할 수 있는 권한을 부여할 수 있습니다.

friend 기능을 클래스단위가 아닌 멤버 함수 단위로 지정해 주는것입니다.

아래 코드를 확인해보시죠.


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
#include <iostream>
#include <string>
using namespace std;
 
class Friend1 {
private :
    string name;
 
    friend void set_name(Friend1&string);
};
 
 
void set_name(Friend1& f, string s) {
    f.name = s;
    cout << f.name << "\n";
}
 
int main(void) {
    Friend1 f1;
 
    set_name(f1, "열코");
 
    return 0;
}
cs


friend 키워드를 사용하여 set_name이라는 함수가 내 친구라는것을 컴파일러에게 알려주는 것입니다.

그래서 set_name 함수에서는 Friend1 클래스의 private 멤버인 name 변수에 접근이 가능한 것이죠.

생각보다 간단하고 쉬운 개념이죠?


* 주의사항

- 친구의 친구는 friend 키워드로 명시하지 않은 경우 친구 관계가 형성되지 않습니다.

- 친구의 자식도 마찬가지로 friend 키워드로 명시하지 않은 경우 친구 관계가 형성되지 않습니다.



이상 'friend 클래스와 함수'에 대해 알아보았습니다.

질문 또는 오타나 잘못된 정보가 있는 경우 댓글로 달아주세요!

공감♡ 버튼을 눌러주시면 더욱 유용하고 좋은 포스팅으로 찾아 뵙겠습니다.



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

C++ 가상 함수(Virtual Function)  (8) 2018.10.19
C++ 연산자 오버로딩  (2) 2018.10.12
C++ 함수 오버로딩  (0) 2018.10.11
C/C++ 메모리 동적할당  (0) 2018.10.11
C++ 클래스 접근제한자  (0) 2018.10.10
C++ 클래스와 객체  (0) 2018.10.09
C/C++ 구조체 사용법 및 예제  (1) 2018.10.08
C/C++ 배열 사용법  (0) 2018.10.05

to Top