관리 메뉴

Value Creator의 IT(프로그래밍 / 전자제품)

[C++] Class, Object, Instance (클래스, 객체, 인스턴스) 본문

1. 프로그래밍/9) 기타

[C++] Class, Object, Instance (클래스, 객체, 인스턴스)

valuecreatort 2019. 7. 23. 18:59
반응형

C++은 객체지향 프로그래밍의 대표적인 언어로써 객체지향 프로그래밍 언어의 구성요소인 클래스를 사용할 수 있습니다.

 

 

☞ 클래스(class)란?

사용자 정의 데이터 유형으로 데이터 멤버 및 멤버 함수가 포함되어 있으며,

해당 클래스의 객체(Object 또는 Instance)를 생성하여 접근(Access)하고, 사용할 수 있습니다.

 

예를들어, 자동차라는 데이터 타입(변수)를 만들고자 할 때, 우리는 여러가지 변수와 함수 중

바퀴의 수, 속도 제한, 주행 거리 등의 공통 속성을 찾아 만들어야 합니다.

 

또한 클래스가 정의 될 때 메모리에 할당되지 않으며 객체가 생성될 때 메모리가 할당됩니다.

 

 

클래스 정의 및 객체 선언 방법?

클래스의 정의 방법은 구조체의 정의 방법과 유사합니다.

아래의 예제를 확인하세요.

 

using namespace std;
 
// 클래스 정의
class member {
 
};
 
int main(void) {
    member m1; // 객체 생성
    
    return 0;
}

 

 

 

class라는 키워드를 사용하여 클래스를 정의하고, 일반 변수 선언하듯이 (int a;) 객체를 생성해서 사용할 수 있습니다.

하지만 구조체와 다른 점으로는 데이터 멤버에 접근 지정자를 지정해 줄 수 있습니다.

접근 지정자는 3가지로 나뉘는데

 

public, private, protected 이렇게 3가지로 나뉩니다.

 

public 멤버는 공개 데이터 맴버로 클래스 내부 및 외부에서도 객체를 통해 접근이 가능합니다.

private 멤버는 비공개 데이터 멤버로 클래스 내부에서만 접근이 가능합니다.

protected 멤버는 보호된 데이터 멤버로 상속된 클래스 한정 접근 가능합니다.

(protected에 대해서는 상속 시간에 더 자세히 알아보겠습니다. ^^)

 

 

public 및 private 접근 지정자는 아래와 같이 지정해 줄 수 있습니다.

#include <iostream>
#include <string>
using namespace std;
 
class member {
private :
    int id;
    string name;
    
public :
    void print_name() {
        cout << name;
    }
 
};
 
int main(void) {
    member m1;
    
    return 0;
}

 

☞ 클래스의 멤버 함수 정의 방법?

멤버 함수를 정의하는 방법은 두 가지가 있습니다.

첫번째는 내부 클래스 정의이며, 두번째는 외부 클래스 정의입니다.

내부 클래스 정의는 말 그대로 클래스 내부에 멤버 함수를 정의하는 것이고,

외부 클래스 정의는 :: 연산자(scope resolution)를 사용해야 합니다.

아래는 외부 클래스 정의의 예제 코드입니다.

 

#include <iostream>
#include <string>
using namespace std;
 
class member {
private :
    int id;
    string name;
    
public :
    // 내부 클래스 정의
    void print_name() {
        cout << name;
    }
 
    // 외부 클래스 정의
    void print_id();
};
 
// 외부 클래스 정의
void member :: print_id() {
    cout << id;
}
 
int main(void) {
    member m1;
    
    return 0;
}

 

 

☞ 생성자, 소멸자?

클래스는 객체가 인스턴스화(객체 생성) 될 때마다 컴파일러에 의해 호출되는 특수 메소드가 있는데,

바로 생성자 라는 함수입니다.

생성자, 소멸자에는 다음과 같은 유형이 있습니다.

 

1. 디폴트 생성자

2. 매개변수 생성자

3. 복사 생성자

4. 소멸자

 

처음 들으신 분들은 많이 생소하실수도 있지만 하나씩 설명해 나가겠습니다.

 

 

1. 디폴트 생성자

첫번째 디폴트 생성자는 사용자가 직접 생성자를 정의해 주지 않아도 알아서 만들어지는 생성자입니다.(눈에 보이진 않습니다.)

내부적으로 알아서 처리되는 녀석인데

이를 사용자가 직접 정의해 줄 수 있습니다.

아래 예제 코드는 디폴드 생성자 예제입니다.

#include 
using namespace std;
 
class Point {
private :
    int x;
    int y;
    
public :
    // 디폴트 생성자
    Point() {
        x = 10;
        y = 15;
    }
    void print() {
        cout << "X : " << x << ", Y : " << y << "\n";
    }
};
 
int main(void) {
    Point p;
    p.print();    
}

 

 

 

 

디폴트 생성자는 위와 같이 사용자가 직접 정의해 줄 수 있습니다.

함수 반환형은 없으며, 함수 이름은 클래스의 이름과 동일합니다.

 

2. 매개변수 생성자

두번째로 매개변수 생성자입니다.

매개변수 생성자를 통해 객체 생성 시 클래스 멤버 변수의 값을 초기화 할 수 있습니다.

아래 예제 코드는 매개변수 생성자 예제입니다.

 

 

매개변수 생성자는 생성자 함수 매개변수로 값을 넘겨받아 클래스 멤버 변수를 초기화 할 때 사용합니다.

매개변수 생성자 안의 this 키워드는 클래스 자신의 객체를 가리키는 특수 키워드로써 자기자신을 의미한다고 생각하시면 됩니다.

#include <iostream>
using namespace std;
 
class Point {
private :
    int x;
    int y;
    
public :
    // 디폴트 생성자
    Point() {
        x = 10;
        y = 15;
    }
    // 매개변수 생성자
    Point(int x, int y) {
        this->x = x;
        this->y = y;
    }
    void print() {
        cout << "X : " << x << ", Y : " << y << "\n";
    }
};
 
int main(void) {
    Point p;
    p.print();    
 
    Point p2 = { 3, 4 };
    p2.print();
}

 

 

3. 복사 생성자

복사 생성자는 기존의 객체를 복사하여 새로운 객체를 생성합니다. 컴파일러는 모든 클래스의 기본 복사 생성자를 제공합니다.

int main(void) {
    Point p;
    p.print();    
 
    Point p2 = p;
    p2.print();
}

 

Point p2 = p; 에서처럼 컴파일러에서 제공하는 디폴트 복사 생성자를 호출하는 모습입니다.

나중에 시간이 되면 이 복사 생성자에 대해서도 자세히 알아보도록 하겠습니다!

 

 

 

 

4. 소멸자

소멸자는 객체의 사용이 모두 끝날 때 컴파일러에서 호출하는 특수 멤버 함수입니다.

생성자와 같이 디폴트 소멸자가 기본적으로 생성됩니다.

보통 클래스 내에서 동적 할당한 메모리를 해제할 때 유용하게 사용됩니다.

 

#include <iostream>
using namespace std;
 
class Point {
private :
    int x;
    int y;
    
public :
    // 디폴트 생성자
    Point() {
        x = 10;
        y = 15;
    }
    // 매개변수 생성자
    Point(int x, int y) {
        this->x = x;
        this->y = y;
    }
 
    // 디폴트 소멸자
    ~Point() {
        cout << "소멸자 호출\n";
    }
    void print() {
        cout << "X : " << x << ", Y : " << y << "\n";
    }
};
 
int main(void) {
    Point p;
    p.print();    
 
    Point p2 = p;
    p2.print();
}

 


객체[Object]와 인스턴스[Instance]

객체와 인스턴스는 객체지향 프로그래밍에서는 거의 비슷한 개념으로 사용되지만
엄밀히 말하면 조금은 차이가 있는 개념이다. 객체지향 프로그래밍이 생성된 원인이
사람의 사고와 가장 비슷하게 프로그래밍을 하기 위해서라고 할 수 있다.
즉 우리 실생활의 모든 것들이 전부 객체로 이루어진 것이다. 넓은 의미에서의 객체라는 것은
보고 만질 수 있고, 이해할 수 있으며 생각이나 행동이 추구하는 바를 의미한다.
즉 객체라는 것은 우리가 인지 하고 있는 구체적인 사물이나 시스템이 될 수도 있고, 구체적이지만
물리적으로 경계가 모호한 강, 안개 등도 객체라 할 수 있는 것이다.
인스턴스란, 예로 우리는 하나의 청사진이 되는 클래스를 정의하면
이 클래스에서 각각 구별이 되는 인스턴스를 얼마든지 만들어 낼 수 있는 것이다.
사람이라는 클래스가 있다면 세계 50억명 이상의 각 개인들의 인스턴스가 있는 것이다.
즉 인스턴스란 클래스의 정의를 통해 만들어진 객체를 의미하는 것이다.
class Test {
Person p1; // Person 타입의 객체
p1 = Person(); // 인스턴스
}
객체지향 프로그래밍적인 관점에서 객체는 클래스의 타입으로 선언되었을 때를
의미하는 것이고, 그 객체가 메모리에 할당되어 실제 사용될 때를 인스턴스라고 하는 것이다.
즉, 인스턴스는 추상화 개념 또는 클래스 객체, 컴퓨터 프로세스 등과 같은
템플릿이 실제 구현된 것이다.
인스턴스화는 클래스 내의 객체에 대해 특정한 변형을 정의하고, 이름을 붙인 다음,
그것을 물리적인 어떤 장소에 위치시키는 등의 작업을 통해, 인스턴스를 만드는 것을 의미한다.

-몇몇 필자들은, 객체지향 프로그래밍에서 클래스를 인스턴스화 한다는 것이,
클래스의 구체적인 인스턴스, 즉 객체를 만드는 것이라고 말한다.
그 객체는 컴퓨터 내에서 실행시킬 수 있는 실행 파일이다.
-객체지향 프로그램 언어인 자바에서는, 클래스로부터 인스턴스화된 객체를, 객체라는 말 대신에
역시 클래스라고 부름으로써 많은 사용자들을 혼란스럽게 한다. 즉 자바에서는,
특정한 클래스를 만들기 위해 클래스를 인스턴스화하며, 그것도 컴퓨터 내에서 동작하는 실행 파일이다.
-객체지향 프로그래밍 개념이 나오기 이전의 데이터 모델링이나 프로그래밍에서는, 인스턴스화라는 것이
관계형 데이터베이스 테이블 내에 새로운 엔트리를 만듦으로써
추상화된 객체로부터 실재(데이터가 들어있는) 객체를 만드는 것도, 한 가지 용례였다.

 

 

 

객체(Object)소프트웨어 세계에 구현할 대상이고, 이를 구현하기 위한 설계도클래스(Class)이며, 이 설계도에 따라 소프트웨어 세계에 구현된 실체인스턴스(Instance)이다.

객체(Object)는 현실의 대상(Object)과 비슷하여, 상태나 행동 등을 가지지만, 소프트웨어 관점에서는 그저 콘셉에 불과하다. 소프트웨어에서 객체를 구현하기 위해서는 콘셉 이상으로 많은 것들을 사고하여 구현해야 하므로, 이를 위한 설계도로 클래스를 작성한다. 설계도를 바탕으로 객체를 소프트웨어에 실체화 하면 그것이 인스턴스(Instance)가 되고, 이 과정을 인스턴스화(instantiation)라고 한다. 실체화된 인스턴스는 메모리에 할당된다.

코딩을 할 때, 클래스 생성에 따라 메모리에 할당된 객체인 인스턴스를 객체라고 부르는데, 틀린 말이 아니다.

인스턴스라고 부르면 더 정확하지만, 개념적으로 인스턴스는 객체에 포함된다고 볼 수 있다.

 

 

반응형
Comments