티스토리 뷰

Programming/C++

[c++]class, 생성자

쩨리쩨리 2018. 3. 7. 12:08
반응형

c++ 에서 class의 개념을 이해하기 위해서는 객체지향(OOP, Object Oriented Programming)이 무엇인지 알 필요가 있다.

 

 

* 객체 지향 : 프로그래밍의 대상이 되는 세상의 사물과 현상 모두를 객체로 담아서 나타내는 것이다. 객체의 개념은 모든 개발자들이 해당 객체를 공통적으로 받아들일 수 있을만한 정의를 내린것이다. 특징으로는 추상화, 캡슐화, 상속, 다형성이 있다.

 

- 추상화 : 독립적으로 표현 불가능한 추상적인 것을 구체화 시키는 행위

- 상속 : 부모의 형질을 물려받아 기능을 공유하여 코드의확장이 쉬움

- 다형성 : 한 객체가 다양한 형태를 지닐수 있으며 코드의 가독성이 좋아짐.

- 캡슐화 : 논리적으로 비슷한 데이터와 기능을 묶어, 이들을 은닉하여 외부로 부터 보호가능하다. 즉, 데이터(객체의 필드, 메소드)를 하나로 묶고, 그 내용을 감추는 것이다. 외부의 잘못된 사용으로 객체가 손상되지 않도록 하기 위함인데, 이때 캡슐안의 메소드는 내부, 외부 클래스를 연결하는 역할로 데이터를 전달해준다. 모든 데이터를 연결할 수 있는게 아니라 접근제한자를 써서 메소드의 사용 범위를 제한해 외부로부터 보호한다.

 

 

 

 

* c ++ 에서의 접근지정자

- c 언어에서 구조체와 공용체를 이용하여 사용자 형식을 정의하는데, 구조체와 공용체에서 멤버 변수만 캡슐화가 가능하였다. c++ 에서는 캡슐화 할 수 있는 대상이 멤버 필드(멤버 변수) 외에도 멤버 메소드(멤버 함수)를 캡슐화 할 수 있다.

- c 언어에서는 모든 멤버들이 어디에서나 접근이 가능했지만, c++에서는 멤버들에 대한 접근 지정자를 통해 접근할 수있는 범위를 다르게 지정할 수 있다. 접근 지정자로 접근 범위를 둠으로써 내부에 중요한 멤버의 접근을 차단하여 정보 은닉화가 가능하여 데이터 신뢰성을 높일 수 있다.

 

 

* c++ 접근 지정자 종류

- public : 외부, 내부 상관 없이 모든 곳에서 접근이 가능

- protected : 상속으로 물려받은 자식만 접근이 가능하다

- private : 내부에서만 접근 가능하다. 필드를 포인터로 지정해서 동적메모리 할당 가능하다(변수 하나하나 메모리 지정할 필요없이 필드 자체를 메모리 할당하면 편함).

 

 

 

* c++ class 내부 구조

1. (일반)생성자함수
2. 복사생성자함수
3. 소멸자 함수
4. 대입연산자 함수

 

 

* 생성자 함수

1. 객체 등록시 자동 호출되어지는 함수
2. 역할 : 객체 필드 초기화(쓰레기값 방지)
             객체등록(디폴트)
3. 생성자는 접근지정자를 주로 public으로 지정
이유: c++에서는 class를 외부에서 만들기 때문에 외부에서 내부를 접근해야해서 public 씀
4. 오버로딩이 가능하다(명시적+암시적)
5. const member function으로 만들수 없다.(final 만들수 x)
6. 리턴 타입이 없다.
7. 함수 이름이 클래스명과 동일하다.
8. 디폴트 생성자 함수는 생성자함수를 명시적으로 제공하지 않을 경우에만 제공된다.

 

 

* 명시적 방법으로 생성자 만들기

 

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>
#include <iomanip>
using namespace std;
 
 
 
class A {
    int a;
    //생성자함수
    //명시하지 않으면 자동으로 접근지정자 private으로 설정되기 때문에 접근지정자 명시 필수
public : 
//다른 접근자를 만날때까지 public
//public 이후에 다른 접근자 없으면 클래스 끝까지 public 적용됨
        
         
    A() {//디폴트 생성자
        a = 0;
        cout << "생성자야" <<a<< endl;
    }
    A(int i) {
        a = i;
        cout << "두번째 생성자야" << a << endl;
    }
 
 
};
 
 
void main() {
 
    //A aa;//java 처럼 메모리 할당할 필요없이 바로 변수로 써도됨
    //다만 메모리 할당 안하면 heap이 아닌 stack에 저장됨
    //A *p = new A;
    //A *p = new A(); 이렇게 써도 되는데 ()가 없으면 인자 안 줄때 사용하는것
    //()쓸때는 인 줄때 사용하는 것
    A aa;
    A bb(9);
}
cs

 

 

* 암시적 방법으로 생성자 만들기

 

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>
#include <iomanip>
using namespace std;
 
 
 
class A {
    int a;
    //생성자함수
    //명시하지 않으면 private기 때문에 접근지정자 명시 필수
public : 
    //다른 접근자를 만날때까지 public
    //public 이후에 다른 접근자 없으면 클래스 끝까지 public 적용됨
 
    //오버 로딩
    A(int i =0) {//인자를 아무것도 안 주면 매개변수가 초기값 0을 받아서 0이 출력
        a = i;
        cout << "디폴트매개변수사용" << a << endl;
    
    }
        
        
 
 
};
 
 
void main() {
 
    //A aa;//java 처럼 메모리 할당할 필요없이 바로 변수로 써도됨
    //다만 메모리 할당 안하면 heap이 아닌 stack에 저장됨
    //A *p = new A;
    //A *p = new A(); 이렇게 써도 되는데 ()가 없으면 인자 안 줄때 사용하는것
    //()쓸때는 인 줄때 사용하는 것
    A aa;
    A bb(9);
}
 
cs

 

 

 

* 암시적 방법으로 동적 메모리 할당하기

 

 

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
#include <iostream>
#include <iomanip>
using namespace std;
 
 
 
class A {
    int a;
    int *p;//필드 초기화하기 위한 포인터
 
    //생성자함수
    //명시하지 않으면 private기 때문에 접근지정자 명시 필수
public : //다른 접근자를 만나기 전, 클래스 끝까지 public 적용됨
    
        
    A(int i=1) {
        p = new int[i];//동적 할당으로 메모리 할당
        //포인터는 배열을 가리키고 있음
        //인자를 안 받았을때는 초기값 1을 받아서 무조건 메모리 1개를 가지는 배열 생성
        //인자를 받았을때는 인자 수만큼 메모리를 가지는 배열 생성
        a = i;
        cout << "메모리 할당한 생성자야" << a << endl;
    }
 
 
};
 
 
void main() {
 
    //A aa;//java 처럼 메모리 할당할 필요없이 바로 변수로 써도됨
    //다만 메모리 할당 안하면 heap이 아닌 stack에 저장됨
    ///A *p = new A;
    //new A(); 이렇게 써도 되는데 ()가 없으면 안줄때 사용하는것
    //()쓸때는 줄때 사용하는 것
    A aa;
    A bb(9);
    
}
cs

 

 

 

 

* 절차지향 메모리 할당과 객체지향 메모리 할당의 차이

메인에서 동적 할당 하는 것은 절차지향으로 모든 기능들을 일일히 동적할당하여 기능을 수행해야 했다면 객체 집합인 class라는 설계도를 만들어 모든 기능들을 동적 할당한다. 그것을 메인에서 불러오면 언제든지 설계도를 불러와서 편하게 객체를 만들 수 있다.

 

 

 

>> 일반 생성자는 여기서 설명을 종료한다. 다음엔 복사생성자를 포스팅 하겠다.

반응형
댓글
공지사항