C 클래스 포인터 - C keullaeseu pointeo

1. 접근 지정자

1) 접근 지정자 종류

class test {
private:
	// private에 선언할 멤버
    // 클래스 내에서만 접근 가능
    
public:
	// public에 선언할 멤버
    // 모든 클래스와 함수에서 접근 가능

protected:
    // protected에 선언할 멤버
    // 클래스 자신과 상속된 자식 클래스만 접근 가능

}

    (1) private

        - 동일한 클래스의 멤버 함수에만 제한함

        - 접근 지정자 설정하지 않으면 디폴트로 private으로 처리됨

        - 보통 멤버 변수는 private으로 지정하는 것이 바람직하다

        ▶ 클래스 외부에서 마음대로 접근하면 안되는 보호해야할 데이터들

        함수를 통해서만 접근가능 하게 만든다

  (2) public

    - 모든 다른 클래스와 함수에 접근 허용

    - 생성자는 무조건 public으로 선언해야 된다 -> 아니면 객체 생성을 못함

  (3) protected

    - 클래스 자신과 상속받은 자식 클래스에만 접근 허용

    - 자식 클래스에서만 선언 가능하게 하기 위해 생성자를 protected로 선언하기도 함

 * 접근 지정은 중복이 가능하다


2. 인라인 함수

C 클래스 포인터 - C keullaeseu pointeo
함수 호출 오버헤드

  - 작은 크기의 함수를 호출하면 함수 실행 시간에 비해 호출을 위해 소요되는 부가적인 시간 오버헤드가 상대적으로 큼

  - 위 문제를 해결하기 위해 inline 함수를 사용함

  - 함수 앞에 inline 키워드를 붙여 선언한다

  - inline을 호출하는 곳에 인라인 함수 코드를 확장 삽입함

  - 이 함수를 이용하면 함수 호출에 따른 오버헤드가 존재하지 않고 프로그램 실행 속도가 빨라진다

    * 오버헤드 : 어떤 처리를 하기 위해 들어가는 간접적인 처리 시간과 메모리 등을 말함

  - 장점 : 프로그램의 실행 시간이 빨라짐

  - 단점 : 인라인 함수 코드의 삽입으로 컴파일된 전체 코드 크기 증가

  < 주의 > : 인라인 함수 제약 사항

    - 인라인은 컴파일러에게 주는 일종의 추천 메시지이기 때문에 컴파일러가 선택적으로 필요에 따라 사용한다

    - 재귀함수, 긴 함수, static, 반복문, goto 문 등을 가진 함수는 사용하지 못함

#incldue <iostream>
using namespace std;

inline int odd(int x){
	return (x % 2);
}

int main(){
	int sum = 0;
    
    for (int i = 1; i <= 10000; i++){
    	if(odd(i))
            sum += i;
    }
    
    cout << sum;
}

   위의 코드가 컴파일러를 거치면 아래와 같이 바뀜

#incldue <iostream>
using namespace std;

int main(){
	int sum = 0;
    
    for (int i = 1; i <= 10000; i++){
    	if(i % 2)  // inline 함수를 호출한 곳의 코드를 바로 삽입함
            sum += i;
    }
    
    cout << sum;
}

  inline odd 함수는 x % 2라는 코드를 실행한다. 컴파일러를 거치면 이 코드가 함수가 있던 자리로 바로 들어간다 (확장)

  - 자동 인라인 함수

    · 클래스 선언부에 구현된 멤버 함수로 inline으로 선언하지 않아도 컴파일러에 의해 자동 인라인 처리됨

    · 생성자를 포함해 모든 함수가 자동 인라인 함수가 될 수 있다

class Circle{
private:
	int radius;

public:
	Circle();
    Circle(int r);
    double getArea();
}

(inline) Circle::Circle(){
	radius = 1;
}

Circle::Circle(int r){
	radius = r;
}

(inline) double Circle::getArea(){
	return 3.14 * radius * radius;
}

  inline으로 선언하지 않더라도 inline 함수로 처리된다.

  컴파일러를 지나 inline 함수로 처리되면 아래와 같은 코드로 바뀐다

class Circle{
private:
	int radius;

public:
	Circle(){
    	radius = 1;  // 자동으로 처리된 인라인 함수
    };
    
    Circle(int r);
    
    double getArea(){
    	return 3.14 * radius * radius;  // 자동으로 처리된 인라인 함수
    };
}

Circle::Circle(int r){
	radius = r;
}

3. 헤더 파일과 cpp 파일 분리

  - 바람직한 C++ 프로그램 작성을 위해선 클래스 헤더 파일과 cpp 파일로 분리해 작성한다

  - 클래스의 재사용을 위해 분리해서 저장하는 것이다

  - 클래스마다 분리 저장 -> 헤더 파일과 cpp 파일의 이름은 같아야 한다

  - 클래스 선언부 : 헤더 파일에 저장 .h로 저장

C 클래스 포인터 - C keullaeseu pointeo

· 헤더 파일에 .h 파일을 저장한다

· 클래스의 선언함

- 클래스 구현부 : cpp 파일 저장, 클래스가 선언된 헤더 파일을 inlcude

C 클래스 포인터 - C keullaeseu pointeo

· cpp 파일은 소스 파일에 저장

· main.cpp와 test.cpp를 컴파일하면 .obj를 각각 생성하고 이를 링크해

 서 main.exe 실행 파일을 만든다

C 클래스 포인터 - C keullaeseu pointeo

옆 코드를 통해 cpp파일에서 헤더 파일을 불러온다

C 클래스 포인터 - C keullaeseu pointeo

  - 헤더 파일을 중복해 인클루드하면 에러가 발생함

#ifndef TEST_H
#define TEST_H  // 위의 조건이 false라면 define하기

// 클래스 선언부


#endif

  - 이를 해결하기 위해 .h 파일에서 #ifndef TEST.H를 통해 헤더 파일 중복 인클루드를 방지한다


4. 객체 포인터

  - 포이터로 클래스 멤버에 접근하기 위해서는 ->를 사용함

  - 변수와 똑같이 객체 포인터 선언은 class*객체명으로 선언함

// Circle 이라는 클래스 선언 & 구현

int main(){
	Circle donut;

	Cirfcle *c;  // 객체 포인터 선언
    c = &donut;  // 객체 포인터에 객체 주소 저장
	
}

  - 객체 포인터로 접근할 수 있는 방법은 아래 2가지가 있다

// 방법 1
c->getArea();   // 객체명->멤버

// 방법 2
(*c).getArea()  // (*객체명).멤버
< 참고 >

명품  C++ 프로그래밍 - 황기태