C++ 객체 지향 프로그래밍(oop)

SOEUN CHOI·2022년 5월 18일
0

C++_study

목록 보기
3/15

씹어먹는 C++

5장 객체지향 프로그래밍(oop) 57p - 187p


객체 지향 언어

object oriented language

  • 추상화 ( Abstraction )

    => 컴퓨터에서 처리 할 수 있도록 현실 세계를 반영하여 함수와 변수화

  • 캡슐화 ( Encapsulation)

    => 변수들을 외부로 보호
    => 객체의 인스턴스 변수의 값은 인스턴수 함수를 통해서 변경 ( 간접적으로 조절 )

    * 사용 이유

    => 객채 내부적인 처리는 알 필요 없도록 함
    => 복잡한 객채의 일들을 내부에서 처리

객체

object

object

variale + method
=> 변수 + 함수

객체에 정의 되면
=> instance variable + instance method
변수들과 참고 자료들로 이루어진 소프트웨어 덩이리

클래스

class

class

객체를 만들기 위한 뼈대 이자 설계도

클래스
=> member variale + member method

c++에서 클래스를 이용해 만들어진 메모리에 객체 => instance

Example code

include <iostream>

class Animal {
  private:
	int food;
	int weight;
  public:
	void set_animal(int _food, int _weight) {
	food = _food;
	weight = _weight;
	}
	void increase_food(int inc) {
	food += inc;
	weight += (inc / 3);
	}
	void view_stat() {
	std::cout << "이 동물의 food : " << food << 	std::endl;
	std::cout << "이 동물의 weight : " << weight << 	std::endl;
	}
}; // 세미콜론 잊지 말자!

int main() {
	Animal animal;
	animal.set_animal(100, 50);
	animal.increase_food(30);
	animal.view_stat();
	return 0;
}

클래스 인스턴스 생성

클래스 이름으로 명시

class 접근 지시자

외부에서의 접근
가능 public
불가능 private < 객체내 보호를 위해 내부에서만 접근 가능
* protected < 상속인 경우에만 접근 가능

키워드 명시 없다면 private으로 설정

맴버 함수

해당 class 내 멤버 변수는 명시 없시 사용 가능

함수의 오버로딩

Overloading

함수의 이름이 같더라도 인자가 다르면 다른 함수라고 판단

example code

#include <iostream>

void print(int x) { std::cout << "int : " << x << std::endl; }
void print(double x) { std::cout << "double : " << x << std::endl; }

int main() {
	int a = 1;
	char b = 'c';
	double c = 3.2f;
	
    print(a);
	print(b);
	print(c);
    
	return 0;

int : 1
int : 99 // char가 아니라 int
double : 3.2

c++ 컴파일러 처리

  1. 자신과 타입이 정확히 일치 함수 찾기
  2. 정확히 일치하는 타입이 없는 경우 비슷한 형변환을 통해 일치하는 함수 찾기
  3. 없다면 더 포괄적인 형변환을 통해 일치하는 함수 찾기
  4. 유저 정의된 타입 변환으로 일치하는 것 찾기

if) 그래도 없다면 or 두 개 이상 같으면 error: ambiguous

생성자 및 소멸자

constructor

객체 생성시 자동으로 호출되는 함수 > 객체를 초기화 해주는 역할

// 객체를 초기화 하는 역할을 하기 때문에 리턴값이 없다!
/* 클래스 이름 */ (/* 인자 */) {}

인자에 맞춰 생성자를 호출하여 객체를 생성

example code

//생성자
Date(int year, int month, int day)

//객체 생성
Date day(2011, 3, 1); // 암시적 방법 (implicit)
Date day = Date(2012, 3, 1); // 명시적 방법 (explicit)

default constructor

디폴트 생성자

생성자 정의를 하지 않아도 컴파일러가 자동으로 추가하여 디폴트 생성자를 호출
인자를 하나도 가지지 않는 생성자

example code

//디폴트 생성자 정의
Date() {
	year = 2012;
	month = 7;
	day = 12;
}
//객체 선언
Date day = Date();
Date day2;
//객제가 아니라 하나의 함수로 인식 됨 *주의*
Date day3(); 

//명시적으로 디폴트 생성자 사용 
class Test {
  public:
	Test() = default; // 디폴트 생성자를 정의해라
};

생성자 오버로딩

디폴트 생성자 제외하고 다른 인자들을 갖는 생성자 정의하여 생성자 오버로딩
클래스의 객체를 여러가지 인자타입으로 초기화 하여 객체 생성 가능

소멸자

Destructor

객체가 소멸 될 때 자동으로 호출 되는 함수
메모리 누수 방지로 동적 할당 delete 할 수 있도록 한다.

  • default destructor
    소멸자가 필요 없다면 구지 적지 않아도 컴파일러가 생성

  • 메모리 누수
    객체내 동적할당 시 객체가 delete된 후 지워질 수 없어
    메모리 공간에 쌓이며 필요없는 메모리 점유를 하게 된다.

  • 소멸자가 불리는 순서 주의
    전역 객체는 전체 프로그램 종료할 때 호출
    지역 객체는 해당 지역이 없어질 때 호출

example code

// 소멸자
~(클래스의 이름)

Marine::~Marine() {
	std::cout << name << " 의 소멸자 호출 ! " << 		std::endl;
	if (name != NULL) {
	delete[] name;
	}
}

복사 생성자

copy constructor

class T 의 객체 a 를 상수 레퍼런스로 받아 복사 하여 객체 생성
const이므로 내부에서 a 데이터 변경은 불가능
새로운 인스턴스 변수 초기화시 데이터 복사하여 사용

  • Default copy constructor
    c++ 컴파일러에서 지원
    대응 되는 원소를 1 대 1로 복사
  • 깊은 복사 /얕은 복사
    깊은 복사
    메모리를 새로 할당해서 내용 복사
    얕은 복사
    단순히 대입만 해서 복사
  • 깊은 복사를 원할 때는 사용자가 직접 복사 생성자 정의

example code

// class T에서 복사 생성자
// T(const T& a);

Photon_Cannon::Photon_Cannon(const Photon_Cannon& pc) {
	std::cout << "복사 생성자 호출 !" << std::endl;
	hp = pc.hp;
	shield = pc.shield;
	coord_x = pc.coord_x;
	coord_y = pc.coord_y;
	damage = pc.damage;
    
    //깊은 복사
    name = new char[strlen(pc.name) + 1];
	strcpy(name, pc.name);
}

//복사 생성자를 이용한 객체 생성 
Photon_Cannon pc1(3, 3);
Photon_Cannon pc2(pc1);
// '=' 이용한 복사 생성자 호출
Photon_Cannon pc3 = pc2;

생성자 초기화 리스트

initializer list

생성자를 호출하는 동시에 멤버 변수를 초기화

  • 초기화 리스 사용 안 할 시
    생성 먼저한 후 대입 수행 < 초기화 리스트가 효율적

  • const
    멤버 변수 정의를 const하여 초기화 후 변경 불가능

example code

// 초기화 리스트
// (생성자 이름) : var1(arg1), var2(arg2) {}

Marine::Marine(int coord_x, int coord_y)
: coord_x(coord_x), coord_y(coord_y), hp(50), damage(5), is_dead(false) {}

static

static 변수

클래스 하나에만 종속되는 변수
어떤 클래스의 static 멤버 변수는 프로그램이 종료 될때 소멸
클래스의 모든 객체들이 공유 하는 하나의 변수

  • static 변수 초기화
    클래스 내부에서는 불가능
    클래스 외부에서 초기화 가능
    const static 변수일때만 내부에서 초기화 가능
  • static 변수 관리
    주로 생성자와 소멸자에 추가해서 사용
int Marine::total_marine_num = 0;

static 함수

객체가 없어도 그냥 클래스 자체에서 호출
클래스 전체에 딱 1 개 존재하는 함수
내부에 그냥 클래스의 멤버 변수들을 이용 불가능< 객체를 지정하지 않으므로

example code

// class 내 함수 선언
static void show_total_marine();

//함수 정의
void Marine::show_total_marine() {
	std::cout << "전체 마린 수 : " << total_marine_num << std::endl;
}
//함수 사용시 class<T>:: (static 함수)형식으로 사용
Marine::show_total_marine();

pointer & reference in class

this

호출하는 객체 자신을 가리키는 포인터
static 함수를 제외한 모든 멤버 함수에 정의 되어 있다

example code

Marine& Marine::be_attacked(int damage_earn) {
	hp -= damage_earn;
	if (hp <= 0) is_dead = true;
	return *this;
}

레퍼런스를 리턴하는 함수

profile
soeun choi

0개의 댓글