[C++] 클래스(Class)(1) 객체로서의 클래스

Gamchan Kang·2023년 4월 10일
0

C++

목록 보기
7/11
post-thumbnail

원래는 <sstream>을 포스팅할 예정이었지만, 순서를 조금 바꿨다.

왜 클래스를 사용하는지 수업을 들으면서 생각해봤다. 클래스는 구조체랑 다르다. 가장 큰 차이를 뽑자면 '정보 은닉'이다. 객체마다 정보를 숨기고 드러내면서 서로 얽힌다. 구조체는 멤버 데이터를 전부 드러내지만, 클래스는 일부만 드러낸다. 이는 동작을 이해하기 쉬워진다.

Feature struct class
Default member access Public Private (by default)
Inheritance Only public inheritance Public and private inheritance
Semantics Typically used for simpler data structures Typically used for more complex data types with behavior
Data representation Can include data members and member functions Can include data members, member functions, and operator overloads

1. 객체(Object)

1-1 객체 vs 클래스 vs 인스턴스(instance)

클래스를 보기 전에 객체와 클래스, 인스턴스의 차이를 볼 필요가 있다. 객체는 추상적인 모든 것, 이를테면 변수, 함수가 있다. 클래스는 객체를 '구성(혹은 디자인)'하기 위한 도구이다. 인스턴스는 객체가 코드 상에 실제로 나타난 것이다. 객체가 개념이라면 인스턴스는 실물로 생각할 수 있다. 하지만 흔히 객체와 인스턴스는 동의어로 사용한다. 앞으로도 객체와 인스턴스를 동일시할 예정이다.

reference


1-2 생성자(constructor)와 메소드(method)

C++에는 생성자가 있다. 객체가 선언(declare)되면 생성자가 객체를 찍어낸다. int a;로 변수를 선언했다면 이미 int 생성자가 어떤 값을 a에 넣었다. 이 값이 의미가 없지만 말이다. 다음 코드를 보자.

#include <iostream>

int main() {
	int a;
    std::cout << a << std::endl;
}

a에 아무 값도 넣지 않았음에도 0이 출력된다. int 생성자는 a가 선언되면서 정수형 0을 생성해서 a에 넣었다.

메소드는 객체 지향 프로그래밍에서 사용되는 개념이다. 객체가 동작하기 위한 방법이다. 위 예시에서 int형 변수에 사용되는 사칙연산 등이 int의 메소드이다.


2. 클래스

2-1 클래스 선언

기본적인 클래스는 다음과 같이 선언한다.

class ClassName { // 클래스 이름
	private:
    	// 클래스 내부에서만 참조(reference)할 수 있는 '객체'
    public:
    	// 클래스 외부에서 사용할 수 있는 메소드
};

위 코드에서 구조체와 다른 점을 확인할 수 있다. private, public이다. privatepublic의 차이는 주석 내용과 같이 참조할 수 있는 범위(scope)이다. 다음 코드를 보면,

#include <iostream>

class Point {
    private:
        int x, y;
};

int main() {
    Point p;
    std::cout << p.x << std::endl;
    return 0;
}

std::cout << p.x << std::endl;에서 메인 함수에서 p.x로 접근하려고 한다. 위 코드를 실행하면 다음과 같은 에러가 발생한다.

위 코드에서 privatepublic으로 바꾸면 값이 출력된다.



2-2 클래스 생성자

클래스도 다른 변수형과 마찬가지로 생성자가 있다. 하지만 int a = 3;과 같이 선언과 동시에 초기화(initialize)하기 위해서 생성자를 직접 만들 수 있다.

class ClassName {
	private:
    	// 멤버 변수
    public:
    	ClassName(초기화 내용) {
        	// 멤버 변수 초기화
        }
        ...
};

앞선 예시에서 생성자를 직접 만든다면 다음과 같다.

...
class Point {
    private:
        int x, y;
    public:
    	Point(int x_, int y_) {		// private 내부 x, y와 구분지어 주기 위함
        	x = x_; y = y_;
        }
};
...
	Point p(3, 4);
...

위 내용을 풀어서 보자면

클래스 객체 p에는 private 멤버 변수 x, y가 있다. 이 xyPoint p(3, 4);에서 각각 34로 초기화됐다.

로 표현할 수 있다.



2-3 클래스 메소드

1) 같은 소스 파일

클래스 메소드, 다른 말로 클래스 멤버 함수는 클래스 내부에서 선언된다.

class ClassName {
	private:
    	// 멤버 변수
    public:
    	int method1(매개변수);	// 선언만
        
        void method2(){			// 선언 및 동작 구현
        	// 함수 내용
        }
};

원의 넓이와 둘레, 중심 좌표 위치를 클래스로 구현했다.

#include <iostream>
#define PI 3.14

class Circle {
    private:
        int cx, cy;
        int r;
    public:
        Circle(int a, int b, int R){
            cx = a; cy = b; r = R;
        }

        double area(){
            return r * r * PI;
        }

        double circum(){
            return 2 * r * PI;
        }

        void printCenter(){
            std::cout << "(" << cx << ", " << 
                                cy << ")" << std::endl;
        }

        void moveCenter(int a, int b){
            cx = a; cy = b;
        }
};

int main() {
    Circle c(3, 4, 2);
    std::cout << "Circle Area: " << c.area() << std::endl;
    std::cout << "Circle Circumference: " << c.circum() << std::endl;
    c.printCenter();

    c.moveCenter(100, 100);
    c.printCenter();
    return 0;
}

2) 다른 소스 파일

다른 소스 파일에서 클래스 멤버 함수 동작을 구현할 때는 다음과 같이 한다.

var_type ClassName::method(argument) { ...

위 코드를 main.cpp, Circle.h, Circle.cpp로 분할하면 다음과 같다.

main.cpp

#include "Circle.h"		// C와 같이 stdlib 폴더 속 헤더가 아닌 헤더는 ""

int main() {
    Circle c(3, 4, 2);
    std::cout << "Circle Area: " << c.area() << std::endl;
    std::cout << "Circle Circumference: " << c.circum() << std::endl;
    c.printCenter();

    c.moveCenter(100, 100);
    c.printCenter();
    return 0;
}

Circle.h

#include <iostream>
#define PI 3.14

class Circle {
    private:
        int cx, cy;
        int r;
    public:
        Circle(int a, int b, int R);
        double area();
        double circum();
        void printCenter();
        void moveCenter(int a, int b);
};

Circle.cpp

#include "Circle.h"

Circle::Circle(int a, int b, int R) {	// 생성자는 return x
	cx = a; cy = b; r = R;
}

double Circle::area() {
	return r * r * PI;
}

double Circle::circum() {
	return 2 * r * PI;
}

void Circle::printCenter() {
	std::cout << "(" << cx << ", " << cy << ")" << std::endl;
}

void Circle::moveCenter() {
	cx = a; cy = b;
}
profile
Someday, the dream will come true

0개의 댓글