10 분 소요

1. 객체

세상의 모든것이 객체이다.

1.1 캡슐화

객체를 캡슐로 싸서 그내부를 보호하고 볼 수 없게 한다.

1.1.1 캡슐화의 목적

객체내 데이터에 대한 보안, 보호, 외부접근 제한

1.2 객체의 일부는 공개된다.

외부와의 인터페이스( 정보교환, 통신)을 위해 객체의 일부분을 공개한다.

1.3 c++객체는 멤버 변수와 멤버함수로 구성된다.

1.3.1 TV객체의 상태:

on/off

채널

음량

1.3.2 행동:

켜기/끄기

채널 증가/감소

음량 증가/감소

멤버 변수:
bool on = true: TV 전원이 켜져 있음을 나타냅니다.
int channel = 8: 현재 TV 채널은 8번입니다.
int volume = 16: 현재 TV 볼륨은 16입니다.
멤버 함수:
void powerOn(): TV 켜는 함수입니다.
void powerOff(): TV 끄는 함수입니다.
void increaseChannel(): 채널을 올리는 함수입니다.
void decreaseChannel(): 채널을 내리는 함수입니다.
void increaseVolume(): 볼륨을 높이는 함수입니다.
void decreaseVolume(): 볼륨을 낮추는 함수입니다.

2. 클래스와 객체

클래스가 붕어빵 

객체가 붕어

2.1 클래스

  • 사용자 정의 자료형이라 생각하면 편하다. (일종의 데이터 형의 역할이라고 생각하면 편하다.
  • 객체를 만들어내기 위한 설계도라고 생각한다.
  • 멤버변수와 멤버 함수를 선언한다.

2.2 객체 (object)

  • 클래스형에 의해 만들어진 실제 사용되는 변수
  • 객체는 생성될 때 클래스의 모양을 그대로 가지고 탄생
  • 멤버 변수와 멤버 함수로 구성

2.3 클래스와 객체 관계

⇒ 클래스

class TV {
    bool on;
    int channel;
    int volume;

public:
    void powerOn() { ... }
    void powerOff() { ... }
    void increaseChannel() { ... }
    void decreaseChannel() { ... }
    void increaseVolume() { ... }
    void decreaseVolume() { ... }
};

⇒ 객체

TV 객체 1

- bool on = true
- int channel = 8
- int volume = 16

- 멤버 함수: `powerOn()`, `powerOff()`, `increaseChannel()`, `decreaseChannel()`, `increaseVolume()`, `decreaseVolume()`

TV 객체 2

- bool on = false
- int channel = 13
- int volume = 5

- 멤버 함수: `powerOn()`, `powerOff()`, `increaseChannel()`, `decreaseChannel()`, `increaseVolume()`, `decreaseVolume()`

3. string 클래스와 vector클래스

(기능은 안외워도 된다.)

3.1 string클래스

문자열에 대한 처리를 제공.

구분 함수 특징
생성자 string str; 디폴트 생성자, 빈 문자열을 가지는 str 이름의 스트링 객체 생성
  string str1(“string”); 문자열 상수 “string”으로 초기화하여 str1 객체 생성
  string str2(str1); 객체 str1 값을 복사한 str2 객체 생성
원소값 접근 str[i] i번째 인덱스에 위치한 문자값을 입력/출력
  str.at(i) i번째 인덱스에 위치한 문자값을 입력/출력
  str.substr(position, length) position 값에서 시작하여 length 만큼의 길이를 가지는 문자열인 subString 값 리턴
합당 / 변경 str1 = str2; 문자열 저장 공간을 설정하고 str2 값으로 초기화
  str1 += str2; str2 문자열을 str1의 뒤에 연결
  str.empty(); str이 빈 스트링일 경우 true 리턴, 그렇지 않으면 false 리턴
  str1 + str2; str2 값을 str1의 끝 부분에 연결된 스트링을 리턴
  str.insert(pos, str2); str2 값을 pos 위치부터 시작하여 str에 삽입
  str.remove(pos, length); pos 위치부터 시작하여 length 크기만큼의 substring을 삭제
  str1 == str2, str1 != str2 두 문자열이 동일한지 비교하여 boolean 값 리턴
  str1 < str2, str1 > str2 문자열 크기 비교 (사전적 순서)
  str1 <= str2, str1 >= str2 문자열 크기 비교 (사전적 순서)
  str1.find(str1) str1에서 str1 값이 처음으로 존재하는 인덱스 값 리턴

3.2 vector클래스 : 동적 배열

실행중에 크기를 변경할 수 있는 배열 기능을 제공한다.

3.2.1 vector클래스의 주요 멤버와 연산자

멤버와 연산자 함수 설명
push_back(element) 벡터의 마지막에 element 추가
at(int index) index 위치의 원소에 대한 참조 리턴
begin() 벡터의 첫 번째 원소에 대한 참조 리턴
end() 벡터의 끝(마지막 원소 다음)을 가리키는 참조 리턴
empty() 벡터가 비어 있으면 true 리턴
erase(iterator it) 벡터에서 it가 가리키는 원소 삭제 후 자동으로 벡터 조절
insert(iterator it, element) 벡터 내 it 위치에 element 삽입
size() 벡터에 들어 있는 원소의 개수 리턴
operator 지정된 원소에 대한 참조 리턴
operator=() 이 벡터를 다른 벡터에 치환(복사)

3.2.2 vector다루기 사례

vector 생성

vector<int> v;

정수 벡터 v 생성

정수 원소 삽입

v.push_back(1);
v.push_back(2);
v.push_back(3);

정수 1, 2, 3 삽입

벡터 v의 상태: [1, 2, 3]

원소 개수 s와 벡터의 용량 c

int s = v.size();      // s는 3
int c = v.capacity();  // c는 7
  • s = 3: 벡터에 있는 원소의 개수는 3
  • c = 7: 벡터의 용량은 7 (벡터의 내부적으로 더 많은 원소를 저장할 수 있도록 공간을 할당)

원소 값 접근 (at() 함수 이용)

v.at(2) = 5;
int n = v.at(1);
  • v.at(2) = 5: 벡터의 2번 인덱스에 있는 값을 5로 변경벡터 v의 상태: [1, 2, 5]
  • n = v.at(1): 벡터의 1번 인덱스에 있는 값을 n에 저장결과: n = 2

원소 값 접근 (연산자 [] 이용)

v[0] = 10;
int m = v[2];  // m은 5
  • v[0] = 10: 벡터의 0번 인덱스에 있는 값을 10으로 변경벡터 v의 상태: [10, 2, 5]
  • m = v[2]: 벡터의 2번 인덱스에 있는 값을 m에 저장결과: m = 5

이처럼 벡터는 push_back()을 통해 동적으로 크기를 조절할 수 있으며, size()와 capacity()를 통해 현재 상태를 확인할 수 있다. at()와 []를 이용해 각각 안전하게 또는 직접적으로 원소에 접근할 수 있다.

3.2.3 vector 클래스 사용하기

#include <iostream>#include <vector>using namespace std;

int main() {
    vector<int> v;  // 정수만 삽입 가능한 벡터 생성

    v.push_back(1); // 벡터에 정수 1 삽입
    v.push_back(2); // 벡터에 정수 2 삽입
    v.push_back(3); // 벡터에 정수 3 삽입

    for(int i = 0; i < v.size(); i++)  // 벡터의 모든 원소 출력
        cout << v[i] << " ";           // v[i]는 벡터의 i번째 원소
    cout << endl;

    v[0] = 10;       // 벡터의 첫 번째 원소를 10으로 변경
    int n = v[2];    // n에 3이 저장
    v.at(2) = 5;     // 벡터의 3번째 원소를 5로 변경

    for(int i = 0; i < v.size(); i++)  // 벡터의 모든 원소 출력
        cout << v[i] << " ";           // v[i]는 벡터의 i번째 원소
    cout << endl;
}

출력 결과:

1 2 3
10 2 5

4. 클래스 작성

클래스는 멤버변수와 멤버함수로 구성된다.

멤버함수는 해당 클래스의 모든 멤버를 직접 사용가능하다. (따로 객체이름을 지정할 필요가 없다.)

클래스 선언부와 클래스 구현부로 구성된다. ⇒

4.1 클래스 선언부

4.1.1 선언부의 주요 구성

  • 멤버변수와 멤버 함수를 선언한다.
  • 멤버 변수는 클래스 선언내에서 초기화할수 없다. ***
  • 멤버 함수는 원형 형태로 선언된다.*** ⇒ 만약에 클래스 선언부에 구현이 되었다면. 자동 인라인 기능이 내재되게 된다.

4.1.2 멤버에 대한 접근 권한 지정

  • 접근 지정자: private, protected, public 키워드
  • 클래스의 멤버를 정의할때 접근 지정자를 사용한다.
  • 디폴트는 private
  • public: 다른 모든 클래스나 객체에서 멤버의 접근이 가능함을 표시한다.

**4.1.3 <클래스 선언부="" 예시="">**

class Circle {
public:
    int radius;               // 멤버 변수
    double getArea();         // 멤버 함수
};
  • class 키워드: 클래스를 선언할 때 사용.
  • public: 멤버에 대한 접근 지정자.
  • 멤버 변수: radius는 원의 반지름을 저장하는 변수.
  • 멤버 함수: getArea()는 원의 면적을 계산하는 함수.

4.2 클래스 구현부

클래스에 정의된 모든 멤버 함수 구현. 클래스 선언부에 함께 구현할 수도 있다.

(여기서 클래스 구현부도 클래스 외부로 간주한다. 따라서, ::를 사용하여야한다.)

4.2.3 <클래스 구현부 예시>

double Circle::getArea() {
    return 3.14 * radius * radius;
}
  • 범위 지정 연산자(::): 클래스 외부에서 멤버 함수를 정의할 때 사용.
  • getArea() 함수: 원의 면적을 계산하여 리턴.

클래스 선언과 구현을 분리하는 이유: ***

  • 클래스 선언을 다른 파일에서 활용하기 위해, 선언과 구현을 분리하여 관리함.

4.3 클래스의 선언부, 구현부 정리

/* Circle 클래스 선언부 */
class Circle
{
    // 클래스 private이 디폴트이다.

public:
    int radius; //멤버 변수 선언
    double getArea(); //멤버 함수 선언
    
    /* 이렇게 선언부에 멤버함수를 구현할 수도 있다.
    double getArea()
    {
        double area = 3.14 * radius * radius;
        return area;
    }*/
};

/*Circle 클래스의 구현부*/
double Circle::getArea() //getArea함수는 Circle클래스의 멤버함수이다.
 {
     double area = 3.14*radius*radius;
     return area;
 }
 
 
 

int main()
{
    Circle A, B, C; // int a,b,c;와 같은 느낌. 객체 A,B,C를 생성.
    A.radius = 10; //A의 멤버 변수인 radius에 접근

    cout << A.getArea() << endl; //A의 멤버함수 호출
    
    B.radius =20;
    
    double area = B.getArea() << endl;
    cout << area << endl;
    

점을 찍으면 사용할수있는 멤버함수와 멤버변수가 보인다.

image.png

5. 객체 생성 및 활용

5.1 객체 이름 및 객체 생성

Circle donut; // 이름이 donut인 Circle 타입의 객체 생성

객체인 타입(클래스 이름) : Circle

객체 이름 : donut

5.2 객체의 멤버 변수 접근

donut.radius =1; //도넛 객체의 radius멤버변수값을 1로 설정한다.

5.3 객체의 멤버함수 접근

double area = donut.getArea(); //도넛 객체의 면적 알아내기

6. 객체의 생성 및 응용

6.1 멤버 변수의 메모리 할당 시점

클래스를 정의한다고 멤버변수가 메모리가 할당되는것이 아니다.

클래스의 객체를 생성하는 시점에 멤버 변수가 메모리에 할당된다!

6.2 멤버변수나 멤버함수에 접근 방법

일반 객체: .연산자를 사용한다.

동적 객체 : →연산자 사용

Circle c1; //일반 객체
c1.radius =2;

Circle *c2 = new Circle; //동적객체, 객체에 대한 포인터
p-> radius =3; 

6.3.1 객체를 가리키는, 객체에 대한 포인터 (멤버변수에 접근)***

Circle *p = &A; (Circle은 클래스이고, A는 객체이다)

(*p).radius

p → radius

6.3.2 객체에 대한 포인터 (멤버함수에 접근)***

cout << (*p).getArea() << endl; // 314
cout << p->getArea() << endl;   // 314
int main()
{
    Circle A, B, C; 
    A.radius = 10;

    cout << A.getArea() << endl;

    Circle *p = &A;  //객체를 가리키는 포인터 선언
    
    cout << (*p).radius << endl; // 10
    cout << p->radius << endl;   // 10  이방식을 더 많이 사용한다.

    cout << (*p).getArea() << endl; // 314
    cout << p->getArea() << endl;   // 314
}

6.3 멤버함수는 멤버변수와 생성프로세스가 다르다.

객체마다 만들어지는것이 아니라, 클래스 전체에 대해서 한번만 정의하고 같은 클래스 객체들이 공유해서 사용

6.3.1 멤버함수에서 사용되는 멤버변수

멤버 함수를 호출한 객체의 것이다.

6.3.2 멤버함수와 전역함수의 차이점

  • 멤버 함수를 호출하려면 객체 이름을 지정해야 한다.
Circle c1;
double area = c1.getArea(); //Circle 클래스의 멤버함수를 호출한다.

getArea(); //전역함수를 의미하므로 컴파일 에러. 
//=> 전역범위에 getArea()라는 함수가 정의되어있지 않으므로

위와 같이 .으로 지정해도되고,

다음과 같이 포인터를 이용해도 된다.

Circle* p = &c1;
double area = (*p).getArea();

6.3.3 멤버함수안에서 같은 클래스에 정의된 멤버변수, 멤버함수에 접근**

  • 객체이름을 지정하지 않아도 된다. (않는다.)***
  • 멤버 함수 안에서는 접근 지정자에 상관없이 클래스의 모든 멤버를 사용가능함.
class Circle {
private:
    int radius;

public:
    double getArea() {
        return 3.14 * radius * radius;  // private 멤버 변수에 접근 가능
    }

    void setRadius(int r) {
        radius = r;  // private 멤버 변수에 접근 가능
    }
};

실습 4-3

int main() {
	Rectangle rect;
	rect.width = 3;
	rect.height = 5;
	cout << "사각형의 면적은 " << rect.getArea() << endl;
}

메인함수가 잘 작동하도록 너비와 높이를 가지고 면적 계산 기능을 가진 Rectangle 클래스를 작성하고, 전체 프로그램을 완성해라.

class Rectangle{
public:
    //멤버변수
    int width; //사각형의 폭
    int height;//사각형의 높이

    int getArea()
    {
        //여기 함수 내에서 선언하는 변수는 멤버가 아닌 지역변수이다.
        int area= width*height;
        return area;

    }
};

int main()
{
    Rectangle rect;
    rect.width =3;
    rect.height =5;
    cout<< "square area is "<<rect.getArea()<<endl;
}

또는

다음과 같이 외부에다가 선언

class Rectangle{
public:
    //멤버변수
    int width; //사각형의 폭
    int height;//사각형의 높이

    int getArea(); // 멤버함수 선언

};
int Rectangle::getArea()
{
    int area = width*height;
    return area;
}

int main()
{
    Rectangle rect;
    rect.width =3;
    rect.height =5;
    cout<< "square area is "<<rect.getArea()<<endl;
}

클래스내에 에러 표시

class Rectangle1
{
private:
    int width;
    int height;

public:
    int Area()
    {
        int area = width * height;
        return area;
    }
    bool setWidth(int input)  //매개변수가 있는 멤버함수
    {
        if (input < 0)
            return false;
        else
        {
            width = input;
            return true;
        }
    }

    bool setHeight(int input) //매개변수가 있는 멤버함수
    {
        if (input < 0)
            return false;
        else
        {
            height = input;
            return true;
        }
    }

    int getWidth()
    {
        return width;
    }
    int getHeight()
    {
        return height;
    }
};

int main()
{
    Rectangle1 rect;
    if (rect.setWidth(3) == false)
    {
        cout << "width error" << endl;
    }
    if (rect.setHeight(5) == false)
    {
        cout << "height error" << endl;
    }
    rect.setWidth(3);
    rect.setHeight(5);
    cout << "width=" << rect.getWidth() << endl;
    cout << "height=" << rect.getHeight() << endl;
    cout << "area=" << rect.Area() << endl;

    return 0;
}

#private 접근 지정자에 대한 추가 설명

접근 가능한 곳:

클래스 내부:

모든 멤버 함수는 private으로 선언된 변수에 직접 접근할 수 있다. 이는 클래스 내부에서 해당 멤버가 필요한 모든 계산과 처리를 할 수 있도록 보장해주기 때문이다.

class Rectangle {
private:
    int width;
    int height;

public:
    void setWidth(int w) {
        width = w;  // private 멤버 변수에 접근 가능
    }

    void setHeight(int h) {
        height = h;  // private 멤버 변수에 접근 가능
    }

    int Area() {
        return width * height;  // private 멤버 변수에 접근 가능
    }
};

여기서 setWidth(), setHeight(), Area()는 모두 private으로 선언된 width와 height에 직접 접근하여 값을 설정하고, 계산할 수 있다.

접근 불가능한 곳:***

클래스 외부(메인함수 포함, 단 함수구현부의 멤버함수에서는 private변수에 접근 가능하다.!):

클래스 외부에서는 private 멤버에 직접 접근할 수 없다. 객체를 생성한 후에도 클래스 외부에서는 private으로 선언된 멤버 변수나 멤버 함수에 직접 접근할 수 없다. 이 때문에 외부에서 접근할 수 있는 public 멤버 함수를 제공하여, private멤버 변수에 간접적으로 접근하거나 값을 수정하도록 해야 한다.

int main() {
    Rectangle rect;
    rect.setWidth(5);  // public 멤버 함수를 통해서 private 멤버 변수에 접근 가능
    rect.setHeight(10);

    // 아래 코드는 에러가 발생함 (private 변수에 직접 접근하려고 하므로)
    // rect.width = 5;  // Error: width is private
    // rect.height = 10; // Error: height is private

    cout << "Area: " << rect.Area() << endl;  // public 함수로 값을 가져옴
}

위의 코드에서 rect.width 또는 rect.height에 직접 접근하려고 하면 **컴파일 에러**가 발생한다. 대신 setWidth(), setHeight() 같은 public 멤버 함수를 사용하여 private 멤버 변수의 값을 설정할 수 있다.

또 다른 예시이다.

#include <iostream>
using namespace std;

class MyClass {
private:
    int privateVar;

public:
    MyClass(int value) : privateVar(value) {} // 생성자

    void setPrivateVar(int value);  // 멤버 함수 선언
    void displayPrivateVar() const; // 멤버 함수 선언
};

// 클래스 외부에서 멤버 함수 구현
void MyClass::setPrivateVar(int value) {
    privateVar = value; // private 멤버 변수에 접근 가능
}

void MyClass::displayPrivateVar() const {
    cout << "Private Variable: " << privateVar << endl; // private 멤버 변수에 접근 가능
}

int main() {
    MyClass obj(10);
    obj.displayPrivateVar(); // Private Variable: 10

    obj.setPrivateVar(20);
    obj.displayPrivateVar(); // Private Variable: 20

    return 0;
}

태그:

카테고리:

업데이트:

댓글남기기