C++ 3주차 객체와 클래스
포인터
사용 방법
자료형 *변수명;
- &변수 : 변수의 주소
변수 : 변수의 값
예시
1 2 3 4 5
char v = 10; char *p; p = &v; cout << v; cout << p;
특징
- 일반적인 변수와 다르게 주소를 저장함
포인터와 배열의 관계
포인터 변수 + 1
- 포인터 변수의 타입의 크기만큼 증가함
배열의 변수
배열의 변수는 배열의 첫번째 공간의 주소 보유
*(p+1) = p[1]
포인터와 배열은 동일한 문법으로 데이터 접근 가능
절차적 프로그래밍
종류
- C, 포트란…
특징
- 작업의 순서를 기반으로 프로그래밍
- 기능에 중점
- 직관적, 공정, 정해진 루틴의 프로그램 잓성에 유리
장점
- 컴퓨터의 처리구조와 유사함
- 실행속도가 빠름
- 프로그램의 흐름을 쉽게 추적이 가능
단점
- 각 코드의 유기성이 높음
- 유지보수의 난이도가 상승
- 새 기능이나 데이터 추가가 힘들고
- 부분 고장시 전체 고장으로 확대
- 유지보수의 난이도가 상승
- 실행 순서가 정해짐
- 코드 순서가 바뀔 경우 동일 결과를 보장하기 힘듬
- 디버깅이 힘듬
구조적 프로그래밍
종류
- C++, C#, Java, Python
- 데이터와 관련된 동작의 그룹을 객체로 정의
- 데이터 중심이며 안정성이 높음
- 데이터와 동작이 변할 때 유지 보수가 유리함
- 데이터와 관련된 동작의 오류가 발생했을 때, 디버깅에 유리함
특징
- 캡슐화
- 속성과 메소드를 하나로 묶고, 실제 내용은 외부에서 접근 할 수 없도록 접근을 제한함
- 추상화
- 객체의 공통적인 속성, 기능만 구현하는 것
- 상속
- 상위 클래스의 속성, 메소드를 하위 클래스에서 전부 구현하는 것
- 다형성
- 하나의 객체가 여러 타입을 가질 수 있는 것
- 오버라이드와 오버라이딩이 존재함
- 하나의 객체가 여러 타입을 가질 수 있는 것
장점
- 모듈화 및 캡슐화 -> 유지보수에 용의함
- 객체지향 언어
- 현실세계와 유사성에 의해 코드 작성이 쉬움
- 객체 자체가 하나의 프로그램
- 재사용 용의
단점
- 상대적으로 속도가 느리며, 많은 메모리를 사용
- 코드 설계에 절차적 프로그래밍에 비하여 많은 시간이 소모됨
클래스
정의
- 객체 생성을 위해 정의된 형식
- 클래스는 객체가 아니며, 실체도 아님
- 멤버 변수/함수 선언
선언 방법
1
2
3
4
class 클래스이름{
public: 접근제한자(private 등 다른 접근 제한자 사용 가능)
변수타입 변수명;
};
구현 방법
1
2
3
함수의 리턴타입 클래스이름 :: 멤버함수명과 매개변수(){
//클래스 내용
}
클래스와 캡슐화
자동차 클래스{
최고속도(속성)
↑(속도제한)
달린다(동작)
}
↑(보호)
관찰자*현재속도만 관찰이 가능)
객체
- 생성될 때 클래스의 모양을 그대로 가짐
- 멤버 변수와 함수로 구성됨
- 메모리에 생성됨
- 실체(Instance)라고도 불림
- 하나의 클래스로 여러 개의 객체를 생성 가능함
- 객체들은 상호 별도의 공간에 생성됨
멤버 변수와 멤버 함수
멤버 변수
- 클래스 내부에 존재하는 데이터
- Ex) 속도, 전진/후진
멤버 함수(메소드)
- 멤버 변수에 대한 접근이 가능함
- 객체의 동작을 정의함
- 달린다, 멈춘, 좌/우 방향전환
예제 1
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
class Circle {
public:
int radius;
double getArea();
};
double Circle:: getArea() {
return 3.14 * radius * radius;
};
int main(){
Circle donut;
donut.radius = 10;
double area = donut.getArea();
cout << "크기: " << area << endl;
Circle pizza;
pizza.radius = 30;
double area2 = pizza.getArea();
cout << "크기: " << area2 << endl;
}
결과
1
2
크기: 314
크기: 2826
예제 2
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
class Rectangle {
public:
int width, height;
int getArea();
};
int Rectangle::getArea() {
return width * height;
}
int main(){
Rectangle rect;
rect.width = 10;
rect.height = 20;
cout << "사각형 면적: " << rect.getArea() << endl;
}
결과
1
사각형 면적: 200
생성자
- 객체가 생성되는 시점에서 자동으로 호출되는 멤버 함수
- 클래스 이름과 같은 멤버 함수
예시
1
2
3
4
5
6
class Circle{
Circle();
Circle(int radius);
}
Circle::Circle(){ }
Circle::Circle(int radius) {}
목적
- 객체 생성 시 객체에 필요한 초기화를 위해
- 멤버 변수 값 초기화, 메모리 할당, 파일 열기, 네트워크 연결…
특징
생성자 이름
- 반드시 클래스 이름과 동일해야 함
생성자는 리턴타입을 선언하지 않음
- 리턴 타입 없음(Void 타입도 불가능)
객체 생성 시 한번만 호출
- 자동으로 호출되며, 임의로 호출이 불가능함
- 각 객체마다 생성자가 실행됨
생성자는 중복 가능
- 생성자는 한 클래스 내에 여러개가 가능함
- 중복된 생성자 중 1개만 실행
생성이 안되있을 경우 기본 생성자가 자동으로 생성됨
- 기본 생성자 - 매개 변수 없는 생성
- 컴파일러에 의해 자동 생성
예제
예제1
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29
class Circle { public: int radius; Circle(); //매개변수가 없는 생성자 Circle(int r); //매개변수가 있는 생성자 double getArea(); }; Circle::Circle() { radius = 10; cout << "반지름 " << radius << " 원 생성" << endl; } Circle::Circle(int r) { radius = r; cout << "반지름 " << radius << "원 생성" << endl; } double Circle::getArea() { return 3.14 * radius * radius; } int main(){ Circle donut; double area = donut.getArea(); cout << "면적 " << area << endl; Circle pizza(30); area = pizza.getArea(); cout << "pizza 면적 : " << area << endl; }
결과
1 2 3 4
반지름 10 원 생성 면적 314 반지름 30원 생성 pizza 면적 : 2826
생성자를 호출하는 생성자
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
//코드 중복 1
Cirlce :: Circle(){
radius = 1;
cout << "반지름 " << radius << " 원 생성 " << endl;
}
//코드 중복 2
Cirlce :: Circle(int r){
radius = r;
cout << "반지름 " << radius << " 원 생성 " << endl;
}
//간소화된 생성자 호출 생성자 코드 구현
Circle :: Circle() : Circle(1){}
Circle :: Circle(int r){
radius = r;
cout << "반지름 " << radius << " 원 생성 " << endl;
}
예시 코드
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35
using namespace std; #include <iostream> class Circle { public: int radius; Circle(); //위임 생성자 Circle(int r); //타겟 생성자 double getArea(); }; Circle::Circle() { radius = 10; cout << "반지름 " << radius << " 원 생성" << endl; } Circle::Circle(int r) { radius = r; cout << "반지름 " << radius << "원 생성" << endl; } double Circle::getArea() { return 3.14 * radius * radius; } int main() { Circle donut; double area = donut.getArea(); cout << "면적 " << area << endl; Circle pizza(30); area = pizza.getArea(); cout << "pizza 면적 : " << area << endl; }
결과
1 2 3 4
반지름 1 원 생성 면적 3.14 반지름 30 원 생성 pizza 면적 : 2826
생성자의 멤버 변수 초기화
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24
class Point { int x, y; public: Point(); Point(int a, int b); }; //생성자 코드에서의 멤버 변수의 초기화 Point :: Point() { x = 0; y = 0; } Point :: Point(int a, int b) { x = a; y = b; } //생성자의 서두에서 초기값으로 초기화하기 Point :: Point() : x(0), y(0) {} //x,y를 0으로 초기화 Point :: Point(int a, int b) : x(a), y(b) {} //x,y를 각각 a, b으로 초기화 //클래스 선언부에서의 직접적인 값 초기화 class Point{ int x=0, y=0; //선언부에서 값을 직접 초기화 . . . };
예시 코드
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20
class Point { int x, y; public: Point(); Point(int a, int b); void Show() { cout << "(" << x << "," << y << ")" << endl; }; }; Point::Point() : Point(0, 0) {} //위임 생성자 Point::Point(int a, int b) : x(a), y(b) {} //타겟 생성자 int main() { Point origin; Point target(10, 20); origin.Show(); target.Show(); }
결과
1 2
(0,0) (10,20)
기본 생성자
특징
객체 생성시 1회 호출됨
- 클래스에 생성자가 없을 경우, 컴파일러가 자동 생성함
- 클래스 내부에 매개변수가 있는 생성자만 있을 경우, 매개변수 없이 객체를 생성할 경우 오류가 발생함
- 매개변수가 없음
예제 코드
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
class Rectangle
{
public:
int width, height;
Rectangle();
Rectangle(int w, int h);
Rectangle(int length);
bool isSquare();
};
Rectangle::Rectangle() { width = height = 1; } //Rect1에서 호출됨
Rectangle::Rectangle(int w, int h) { width = w, height = h; } //Rect2에서 호출됨
Rectangle::Rectangle(int length) { width = height = length; } //Rect3에서 호출됨
bool Rectangle::isSquare() {
if (width == height) return true;
else return false;
}
int main(){
Rectangle rect1, rect2(3, 5), rect3(3);
if (rect1.isSquare()) cout << "rect1은 정사각형" << endl;
if (rect2.isSquare()) cout << "rect2은 정사각형" << endl;
if (rect3.isSquare()) cout << "rect3은 정사각형" << endl;
}
결과
1
2
rect1은 정사각형
rect3은 정사각형
이 기사는 저작권자의 CC BY 4.0 라이센스를 따릅니다.