Mt.Hwang 2024. 4. 21. 16:05

 * c++ 구조체 변수 선언
구조체명 변수명;
ex) Car myCar;

c와 다르게
 1. struct 키워드 사용 없이 구조체 변수 선언이 가능
 2. 구조체 안에 함수를 삽입 가능

구조체 안에 함수만 선언하고
함수 정의는 밖에서 할 수 있다
ex)
struct Car { void func(); }
void Car::func() {}

구조체 안의 함수는 inline 선언된 것으로 간주


 * 클래스와 구조체의 차이점
외형적 차이는 키워드 밖에 없다
 1. 구조체는 struct 사용
 2. 클래스는 class 사용

다만 클래스는 접근 제어 관련 선언을 추가해주어야 한다


 * 접근제어 지시자
 1. public
 2. protected
 3. private

 public
어디서든 접근 가능

 protected
상속관계에 놓였을 때
자식 클래스에서 접근 가능

 private
클래스 내에서 정의된 함수에서만 접근 가능

접근제어지시자 :
  변수 선언
  함수 선언

ex)
private :
  int num = 10;
public :
  void func();


 * 객체, 멤버변수, 멤버함수
 객체
클래스에 의해 생성된 변수

 멤버변수
클래스 내에 선언된 변수

 멤버함수
클래스 내에 정의된 함수


 * c++의 파일 분할


 * 객체지향 프로그래밍
 객체
물건 또는 대상

 객체지향 프로그래밍
객체 중심의 프로그래밍
현실에 존재하는 사물과 대상, 그리고 그에 따른 행동을
있는 그대로 실체화 시키는 형태의 프로그래밍

동작 중심이 아닌
사물과 사물의 행동

ex) 나는 과일장수에게 두 개의 사과를 구매헀다
객체는 나, 과일장수, 사과
데이터는 두 개
행위 (기능)는 구매했다

객체를 이루는 것은
 1. 데이터
 2. 기능


 * 클래스 정의
class 클래스명 {};
세미 콜론 조심
ex) class Car{};

객체 선언은
클래스명 객체명
ex) Car myCar;

클래스 정의에서
선언과 동시에 초기화는 불가능하다


 * 객체 생성
 1. 일반적인 변수 선언 방식
 2. 동적 할당 방식

일반적인 변수 선언 방식의 객체 생성
클래스명 객체명;
ex) Car myCar;

동적 할당 방식의 객체 생성
클래스명 * 객체명 = new 클래스명;
ex) Car * myCar = new Car;


 * 정보 은닉
외부에서 멤버 변수로 접근하는 것을 막는 것
private을 사용한다

외부의 접근으로 인해
잘못된 값이 저장되는 문제를 방지

private 선언한 변수에 접근하는 함수를 별도로 정의해서
안전한 형태로 멤버 변수의 접근을 유도하는 것이 핵심이다
즉 private으로 변수 선언만 하고
public의 함수로 변수에 값을 할당한다


 * const 함수
같은 클래스에 선언된 멤버 변수의 값을 변경할 수 없는 함수

자료형 함수명() const;
ex) int func() const;

즉 멤버 함수를 이용한
멤버 변수의 간접적인 변경 가능성을 차단한 것

또한 const로 상수화 된 객체를 대상으로는
const 멤버 함수만 호출할 수 있다


 * 생성자
멤버 변수의 초기화에 사용되는 함수
클래스와 동일 이름의 함수로
반환형이 선언되지 않고
실제로 반환하지도 않는다

생성자는 함수의 일종이므로
오버로딩과 디폴트 값 설정이 가능하다


 * 멤버 이니셜라이저 기반의 멤버 초기화
한 클래스가 private 변수로
다른 클래스의 객체를 가질 때 사용

과정은
 1. 메모리 공간 할당
 2. 이니셜라이저를 이용한 객체(멤버 변수) 초기화
 3. 생성자 몸체 부분 실행

이니셜라이저 초기화는
선언과 동시에 초기화라고 생각하면 된다

생성자명() : 객체명(), 객체명() {}
ex) Rectangle 클래스가 private으로 Point 클래스의 객체를 가지는 경우에
Rectangle(int x1, int y1, int x2, int y2) : upLeft(x1, y1), upRight(x2, y2) {}

이니셜라이저를 이용해
변수 및 상수를 초기화시킬 수도 있다
생성자명() : 변수명(값) {}
ex) car() : price(100) {}

이니셜라이저의 초기화는 선언과 동시에 초기화 되는 형태이므로
참조자의 초기화 역시 가능하다


 * 디폴트 생성자
생성자를 정의하지 않을 때 만들어지는 생성자
컴파일러에 의해서 자동으로 추가된다

따라서 모든 객체는 생성자의 호출 과정을 거쳐서 완성된다


 * 생성자 불일치
호출과 생성자 사이에서
매개변수가 일치하는 것이 없는 경우

즉 생성자가 알맞은 형태가 없는 경우


 * 소멸자
객체 소멸 시 자동으로 호출된다

~소멸자명() {}
ex) ~Car() {}

생성자에게 할당한 메모리 공간을 소멸시키지 좋은 위치가 소멸자이다


 * 객체 배열
객체로 이루어진 배열
배열 생성시 객체가 함께 생성된다
void 생성자가 자동으로 호출된다

방법은
 1. 클래스명 배열명[크기];
 2. 클래스명 * 배열명 = new 클래스명[크기];

ex) Person arr[3];

ex) Person * arr = new Person[3];


 * 객체 포인터 배열
객체를 저장할 수 있는 포인터 변수로 이루어진 배열
별도의 객체 생성 과정을 거쳐야 한다

클래스명 * 배열명[크기];
배열명[인덱스] = new 클래스명();

ex)
Person * arr[3];
arr[0] = new Person();
arr[1] = new Person();
arr[2] = new Person();

객체 포인터 배열로 객체를 입력받을 경우
멤버 변수 사용은
배열명[인덱스]->멤버함수명()
으로 해야 된다

ex) arr[0]->func();

arr[0].func()는 사용 불가능


즉 객체 배열은 void 생성자를 디폴트로 사용하는 것
객체 포인트 배열은 입맛에 따라 생성자를 사용하는 것


 * this 포인터
this가 사용된 객체 자신의 주소값을
정보로 담고 있는 포인터

따라서 this 포인터는 그 값이 결정되어 있지 않다

this->변수명
ex) this->num1 = num1


 * Self-reference의 반환
this 포인터를 이용한 반환

클래스명 & 함수명() {
  return * this;
}


 * const와 함수 오버로딩
const 선언 유무는
함수 오버로딩의 조건이 된다

일반 객체나 참조자는 일반 함수를 호출하고
const 객체나 const 참조자는 const 선언된 함수를 호출한다


 * 클래스의 friend 선언
private 멤버의 접근을 허용하는 선언

private 영역에
friend class 클래스명;
ex)
private :
  friend class Girl;

friend로 선언된 클래스는
firend로 선언한 클래스의 private 멤버에
직접 접근할 수 있다

friend 선언은 정보 은닉에 반하는 선언이므로
제한적으로 사용해야 한다


 * 함수의 friend 선언


 * static 멤버 변수 (클래스 변수)
static 변수는 객체 별로 존재하는 변수가 아니라
프로그램 전체 영역에서 하나만 존재하는 변수

프로그램의 실행과 동시에 초기화되어
메모리 공간에 할당된다

클래스의 모든 변수가
static 멤버 변수에 접근한다

ex) 클래스가 객체를 만든 횟수 카운트

static 변수를 외부에서 접근하려면
해당 변수를 public으로 선언해야 한다


 * static 멤버 함수
선언된 클래스의 모든 객체가 공유한다

public으로 선언되면
외부에서 클래스의 이름을 이용해서 호출이 가능하다

클래스명.함수명
ex) Car.speedUp();

객체의 멤버로 존재하는 것이 아니다

static 함수는
 1. static 변수에만 접근 가능하고
 2. static 함수만 호출 가능하다

static 함수는 객체 내에 존재하는 함수가 아니므로
멤버 변수나 멤버 함수에 접근이 불가능하다


 * const static 멤버
클래스가 정의될 때
지정된 값이 유지되는 상수


 * 연산자 오버로딩
클래스명 operator연산자() {}
ex)
Point operator+(const Point & ref) {
  func() + ref.func();
  return num;
}

pos1+pos2는
 1. pos1.operatior+(pos2)
 2. operator+(pos1, pos2)

매개변수 디폴트 값 설정은 불가능하다

연산자의 순수 기능까지 빼앗을 수 없다