본문 바로가기

프로그래밍/C++ language

9. 객체(object)와 클래스(class)

9.2 객체(object)와 클래스(class) 정의

 

- 객체지향 프로그래밍(Object-Oriented Programming)에서는 객체(object)를 사용함

- 명확하게 구별되는 실제세계의 개체(요소)임 ex)책상, 원, 버튼 등

- 이러한 요소를 만들어 내기 위해 정의된 틀이 있음, 그것이 class임, 즉 객체 생성을 위한 설계도

- class에는 객체가 가지는 데이터 필드, 생성자 함수, 객체 함수에 대한 것이 정의되어 있음

- 함수와 데이터필드를 객체의 member라고 함

 

ex)

class Circle{ //프로그래머가 만든 클래스는 첫분자 대문자

public: //공용으로 쓸 수 있음을 의미

double radius;

// 객체의 데이터 필드

Circle(){

radius = 1;

} //데이터 필드값을 주지 않고 생성할 경우 (constructor)

Circle(double newRadius){

radius = newRadius;

} //데이터 필드값을 주고 생성할 경우 (overloading된 constructor)

double getArea(){

return radius * radius * 3.14159;

} //객체의 함수

}

int main(){

Circle circle1(); // radius = 1인 원1 생성

Circle circle2(3); // radius = 3인 원2 생성

circle1.getArea(); // 원1의 면적

...

}

 

9.4 생성자(constructor)

 

- constructor은 객체를 생성하는 특별한 함수임

- class와 이름이 같아야하고, return을 써주지 않음, 객체 생성시 데이터 필드 초기화 역할 수행

 

ex)

class Circle{

public:

double radius; //데이터필드는 초기값 가지지 않음

Circle(double newRadius){

radius = newRadius; //생성자에서 데이터필드 초기화

}

...

}

 

9.5 객체 구성과 사용

 

- Classname objectName(arugment) 의 방법으로 객체를 생성

- Classname은 int, double과 같은 자료형 위치에 들어가므로 class를 자료형이라고 할 수 있음

- 동일한 클래스의 객체의 경우, 대입연산이 가능

- 배열과 같이, 생성된 객체의 이름은 다른 것을 객체를 가리키도록 할 수 없음

- 객체의 size는 함수를 제외한 데이터 필드 부분만임, 함수는 하나의 복사본만을 생성하여 객체가 공유

- 객체이름이 없는 anonymous object 생성가능

 

ex)

Circle circle1;

Circle circle2(2);

circle1 = circle2; // 데이터필드가 복사되어 들어감

circle1 = Circle(); // anonymous object

 

9.6 클래스의 정의(definition)과 구현(implementation)의 분리

 

- 클래스의 정의는 데이터 필드, 생성자, 함수를 정의하는 것이며,

- 클래스의 구현은 정의해놓은 것들을 실제로 작성하는 것임

 

ex)

// Circle.h 파일

 

class Circle

{

public:

double radius;

 

Circle();

Circle(double);

 

double getArea();

}; // 생성자와 함수의 실제 구현은 cpp파일에서 구현

 

// Circle.cpp 파일

 

#include "Circle.h" // 정의된 부분 헤더파일로 포함

 

Circle::Circle() //'::'은 binary scope resolution operator로, 정의된 클래스의 원본이 어디 있는지 알려줌

{

radius = 1;

}

Circle::Circle(double newRadius)

{

radius = newRadius;

}

double Circle::getArea()

{

return radius * radius * 3.14159;

}; // 생성자와 함수의 실제 구현

 

9.7 다중 포함 방지

 

- 여러 header파일에서 동일한 이름의 class가 정의될 경우, 중복으로 class가 정의되어 오류가 발생함

- 이를 해결하기 위해, header 작성시 inclusion guard를 사용할 수 있음

 

ex)

#ifndef CIRCLE_H // 아래 구문이 정의되어있지 않다면 새롭게 정의, 정의되어있다면 기존것 유지

#define CIRCLE_H

 

class Circle{

...

};

#endif

 

9.8 클래스 함수의 인라인

 

- 클래스 정의 내부에서 구현된 생성자와 함수의 경우, 자동으로 인라인 함수가 됨

- 클래스의 구현부에서만 구현된 일반함수의 경우에는 인라인 함수가 아님

- 따라서, 코드가 짧을 경우 inline하여 성능을 향상시킬 수 있음

 

ex)

class A{

...

inline double A::f2(){ //정의되지 않은채 구현된 일반함수를 인라인

...

}

...

}

 

9.9 데이터필드 캡슐화(data field encapsulation)

 

- 데이터필드를 public으로 할 경우, 함수가 아닌 다른 방식으로 데이터가 임의로 수정될 수 있음

- 따라서, 데이터 필드는 private로 선언하고, 값을 확인하고 변경하는 것을 함수로 구현하여 접근하도록 해야함

 

#ifndef CIRCLE_H

#define CIRCLE_H

 

class Circle

{

public:

Circle();

Circle(double);

double getArea();

double getRadius(); //radius의 값을 반환하는 함수(데이터 필드 값 확인기능)

void setRadius(double); //radius의 값을 설정하는 함수(데이터 필드 값 변경기능)

 

private:

double radius;

};

 

#endif

 

9.10 변수의 범위(variable scope)

 

- 클래스 내부에서 선언된 데이터 필드는 클래스 내부 어느 위치에 선언되든, 클래스 내부에서 사용가능

- 클래스 내 함수는, 데이터 필드와 동일한 이름을 가진 지역 변수를 선언할 수 있지만, 피하는 것이 좋음

 

ex)

class A{

public:

...

func1(){

int x = 10; //데이터 필드와 동일한 이름, local value

}

...

private:

int x;

};

 

9.11 클래스 추상화(abstraction)와 캡슐화(encapsulation)

 

- 클래스의 구현과 사용을 분리하는 것을, 클래스의 추상화라고 함

- 클래스를 구현한 사람은, 필드와 함수에 대한 정보를 class contract(클래스 규약)의 형태로 사용자에게 제공함

- 사용자는 클래스의 구현 세부적인 구현 내용을 알 필요 없이 추상적인 형태로 사용(abstraction, encapsulation)

 

ex)

//Loan.h

#ifndef LOAN_H

#define LOAN_H

 

class Loan{

...

double getLoanAmount();

...

}; //정의부분, header

 

//loan.cpp

#include "Loan.h"

 

Loan::Loan(){

...

double Loan::getLoanAmount(){

return loanAmount;

}

...

 

}; //구현부분, cpp

 

//main함수

#include "Loan.h"

int main(){

Loan loan;

cout << loan.getLoanAmount() << endl;

...; // 사용자가 사용하는 부분, main함수

}