[c++] 객체와 클래스

Object Oriented Programming


객체지향 언어: 추상화, 캡슐화, 상속, 다형성을 사용하여 유연성과 모듈성, 명료함 재사용성을 제공하는 부가된 특징을 가지고 있는 강력한 절차형 언어

- 모든 객체의 속성행동을 결합시킴으로써 실제 세계를 반영하는 방법으로 프로그램 구성

- 객체의 관점에서 생각하고, 프로그램은 상호작용하는 객체들의 모임으로 볼 수 있음

 

 

객체 : 명확히 확인이 가능한 실제 세계에서의 존재물을 대표하는 것. 책상, , 대여 등

- 객체는 자신만의 특성과 상태, 행동을 갖는다.

상태(정적) : 현재 값을 가지고 있는 데이터 필드(= 속성)에 의해 표현됨=> 변수

행동(동적) : 일련의 함수에 의해 정의된다. 객체에 대한 함수를 호출하는 것은 객체에게 어떤 일을 수행하도록 요구하는 것=> 함수

ex) 원 객체 : radius / getArea()

 

객체는 상태와 행동 모두를 가짐

상태는 객체 자체를 정의하고, 행동은 객체가 무엇을 할 것인지를 정의하는 것이다.

 

클래스 : 객체의 데이터와 함수가 무엇이 될지를 결정하는 템플릿이며 설계도

객체 : 클래스의 인스턴스

>> 클래스의 여러 가지 인스턴스를 만듦 : 실체화

 

UML 표기법 / (UML) 클래스다이어그램

 

class Circle { // 클래스 - 아직 객체 아님

public :

double radius; // 데이터필드(속성)

// 생성자 - 오버로딩

Circle() { // 인수 없는 생성자

radius = 1; 

}

Circle(double newRadius) { // 인수 있는 생성자

radius = newRadius; 

}

double getArea() { // 일반 함수

return radius * radius * 3.14159;

}

};


생성자

- 특별한 유형의 함수.

- 새로운 객체가 생성될 때 호출됨.

- 일반적으로 객체의 데이터 필드에 초기 값을 주는 초기화 과정을 수행하기 위해 설계됨

- 클래스 이름과 같음

- 여러 개의 생성자 사용 가능 - 오버로딩

>> 초기 데이터 값을 갖는 객체 구성을 쉽게 해줌

- 인수 없는 생성자 / 인수 있는 생성자

- 기본 생성자 : 인수 없는 생성자 + 비어 있는 바디 => 어떠한 생성자도 선언하지 않을 경우에만 자동적으로 주어짐

 

일반함수와의 차이점

1. 생성자는 클래스와 같은 이름을 가짐

2. 생성자는 반환 값 유형을 가지지 않음 (void 주의)

3. 생성자는 객체가 생성될 때 호출된다. 객체를 초기화하는 역할.

 

객체이름

- 객체를 생성할 때 이름을 할당할 수 있음

>>> 객체가 생성될 때는 생성자가 호출됨! (객체 생성 = 생성자 호출)

>> 생성자 이용

인수 없는 생성자 -> 클래스명 변수명()

인수 있는 생성자 -> 클래스명 변수명(인수);

 

>>> 객체 이름으로 접근 가능!

.을 이용하여 데이터 접근, 함수 호출

 

 

int main() {

Circle circle1;

Circle circle2(5.0);     // 다른 데이터 필드. 같은 함수 공유

cout << "Radius: " << circle1.radius <<" Area: " << circle1.getArea();    // circle1radiusgetArea()값 출력

circle2.radius=100;         // circle2radius100으로 변경하고

cout << "Radius: " << circle2.radius <<" Area: " << circle2.getArea();   // radiusgetArea 값 출력

return 0;

}

 

· public : 모든 데이터 필드, 생성자, 함수가 클래스의 객체로부터 접근될 수 있다는 것을 나타내는 것. (default - private)

 

· 클래스 멤버로서 데이터 필드를 선언할 때는 초기화 불가

-> 생성자에서의 초기화만 가능!!! // double radius = 5; ( )

 

· circle1 = circle2 // 객체 복사

복사 후에도 여전히 두 개의 객체(함수는 계속해서 공유)

· 종종 객체를 생성하고 단지 한 번만 객체를 사용하는 경우(객체가 후에 참조되지 않을 때)

>>> 익명객체 : 이름을 줄 필요 없음

클래스명(), 클래스명(인수) // circle1= Circle(5);

 

 

이전에는 같은 파일 안에서 main 함수와 함께 클래스를 선언.

-> 다른 프로그램에서는 이들 클래스를 사용할 수 없게 됨

-> 재사용하기 위해서 분리된 헤더파일 선언!

클래스 선언(.h) : 클래스 안에 어떤 데이터와 함수가 있는지를 컴파일러에게 알려주는 것

>> 모든 데이터 필드, 생성자 원형, 함수 원형

클래스 구현(.cpp) : 어떻게 함수가 동작하는 지를 컴파일러에게 알려주는 것

>> 생성자와 함수도 정의

 

Circle.h

Circle.cpp

class Circle {

public :

double radius;

Circle() ;

Circle(double);

double getArea() ;

};

#include "Circle.h"

Circle::Circle() {

radius = 1;

}

Circle::Circle(double newRadius) {

radius= newRadius;

}

double Circle::getArea() {

return radius* radius * 3.14159;

};

TestCircleWithDeclaration.cpp (client)

#include <iostream>

#include "Circle.h"

using namespace std;

 

int main() {

Circle circle1;

Circle circle2(5.0);

...

return 0;

}

 

· 이항영역결정연산자

ex) Triangle::getArea() Triangle 클래스에 정의되어있는 getArea()

포인터를 사용한 객체 멤버 접근

Circle circle1;

Circle *pCircle = &circle1;

>>>> circle1.radius / (*pCircle).radius / pCircle -> radius

 

힙에서 동적 객체 생성

- 스택 안에서 생성된 객체는 함수가 반환될 때 스택에서 삭제됨

- 객체를 남기기 위해서는 new연산자를 사용하여 힙에서 동적으로 생성해야 함

ClassName *pObject = new ClassName();

ClassName *pObject = new ClassName(인수);

- 객체를 확실하게 삭제하기 위해서는 delete연산자

delete pObejct;

 

데이터 캡슐화

- public은 직접 수정이 가능 // cricle1.radius=5;

-> 데이터가 함부로 수정될 수 있음

-> 클래스를 유지하기 어렵게 하고 버그도 발생하기 쉽게 만듦

>> 데이터필드 캡슐화: 속성에 대한 직접적인 수정을 피하기 위해 private 사용!

 

private

- 클래스 밖에서는 직접 참조를 통하여 접근할 수 없음

>> get함수(게터, 접근자) : 해당 변수를 호출하는 함수

>> set함수(세터, 변경자) : 변수를 직접 수정하는 변수

 

<Circle.h>

<Circle.cpp>

 

class Circle {

public :

Circle();

Circle(double);

double getArea();

double getRadius();

void setRadius();

private :

double radius;

};

 

#include "Circle.h"

Circle::Circle() {

radius = 1;

}

Circle::Circle(double newRadius) {

radius= newRadius;

}

double Circle::getArea() {

return radius* radius * 3.14159;

}

double Circle::getRadius() {

return raidus;

}

void Circle::setRadius(double newRadius) {

radius =(newRadius >=0) ? newRadius :0;

}

 

<TestCircleWithDeclaration.cpp> (client)

#include <iostream>

#include "Circle.h"

using namespace std;

 

int main() {

Circle circle1;

Circle circle2(5.0);

circle2.setRadius(100);   // circle2radius100으로 변경하고

cout<< "Radius : " << circle2.getRadius << " Area: " << circle2.getArea();   // radiusgetArea 값 출력

return 0;

}

 

p287 리스트9.8

this 포인터

: 숨겨진 데이터 필드를 호출 개체로 참조할 수 있도록 특별히 제작된 포인터

 

Circle::Circle(double radius) {

this->radius = radius;

// (*this).radius = radius

}

 

객체를 함수로 전달하는 방법

1) 값에 의한 전달

2) 참조에 의한 전달

3) 포인터를 통한 참조에 의한 전달

 

객체의 배열

Circle circleArray[10];

Circle circleArray[3] = {Circle(3), Circle(4), Circle(5)};

// 인수있는 생성자로 배열 초기화

 

일반 변수와 같아! 단지 객체단위라는 거!

 

생성자 초기화 목록 :

: 생성자에서 필드를 초기화하는 작업만을 할 때

ClassName(parameterList) : datafield1(value1), datafield(value2)

{ // 생성자가 할 일 }

 

 

반응형
그리드형

댓글

❤️김세인트가 사랑으로 키웁니다❤️