본문 바로가기

명품 C++

[명품 C++] 3. 클래스와 객체

3.1 객체에 대한 이해

캡슐화 : 객체의 구성 요소들을 캡슐로 싸서 보호하고 볼 수 없게 하는 것

객체들은 서로 정보를 교환하고 통신하기 위해 일부 요소의 공개 노출이 필요하다

객체 구성 요소

- 멤버 변수 : 객체의 상태를 나타내는 속성

- 멤버 함수 : 행동을 구현한 코드

C++ 클래스와 객체

클래스 : 객체를 정의하는 틀 혹은 설계도, 클래스에 멤버 변수와 멤버 함수를 선언한다

ex) 클래스는 붕어빵 틀, 객체는 붕어빵

클래스는 컴파일이 끝나면 사라지지만, 프로그램은 실행 중에 객체를 생성하여 멤버 변수에 값을 저장하기도 하고 멤버 함수 코드를 실행하기도 한다. 클래스를 통해 생성된 객체들은 별도 공간에 생성된다. 

 

 

 

3.2 클래스 만들기

class 키워드 사용 : 클래스 선언부 + 클래스 구현부

클래스 선언부 예시

- 멤버 변수는 클래스 선언부에서 초기화 가능

- 멤버 함수는 원형 상태로 선언되며, 리턴 타입, 매개 변수 리스트 등이 모두 선언되어야 한다

- 멤버를 외부에 공개하려면 public 접근 지정자를 선언한다

- 접근 지정의 디폴트는 private고, private로 지정하면 아무 접근 지정이 없고, protected 접근 지정은 상속 관계에서 적용된다

class Circle{
	int a; //디폴트 접근 지정은 private
    public: //멤버에 대한 접근 지정자
        int radius;
        double getArea();
}; //반드시 세미콜론으로 끝남!!

클래스 구현부 예시

- 범위 지정 연산자(::)를 사용하여 클래스 이름과 함께 멤버 함수를 기술해야 한다

double Circle::getArea(){
    return 3.14*radius*radius;
}

 

 

 

3.3 객체 생성과 객체 활용

- 객체가 생성되면 클래스 크기의 메모리가 할당된다

- 객체의 멤버에 접근하기 위해서는 객체이름.멤버 형식을 사용한다

#include <iostream>
using namespace std;
class Circle{
    public: //멤버에 대한 접근 지정자
        int radius;
        double getArea();
}; //세미콜론으로 끝남 

double Circle::getArea(){
    return 3.14*radius*radius;
}
int main() {
    Circle donut; //객체 donut 생성
    donut.radius = 1; //객체 반지름을 1로 생성
    double area = donut.getArea();
    cout<< "donut 면적은 " << area << "\n";
    
    Circle pizza; //객체 pizza 생성
    pizza.radius = 30; //객체 반지름을 30으로 생성
    area = pizza.getArea();
    cout << "pizza 면적은 " << area << "\n";
}

이 예시에서 donut 객체는 main()에 의해 생성되었으므로 area 변수와 함께 main()의 스택에 존재한다.

예제 3-2)

#include <iostream>
using namespace std;
class Rectangle{
    public: //멤버에 대한 접근 지정자
        int width;
        int height;
        int getArea();
}; //세미콜론으로 끝남 

int Rectangle::getArea(){
    return width*height;
}
int main() {
    Rectangle rect; //객체 rect 생성
    rect.width = 3; //객체 width를 3으로
    rect.height = 5; //객체 height를 5로
    cout<< "사각형의 면적은 " << rect.getArea() << "\n";
}

 

 

 

3.4 생성자

클래스는 객체가 생성될 때 자동으로 실행되는 생성자라는 특별한 멤버 함수를 통해 객체를 초기화한다.

한 클래스에는 여러개의 생성자를 둘 수 있으나, 이 중 하나만 실행된다.

생성자의 특징

- 객체가 생성될 때 필요한 초기 작업을 하기 위해서 

- 생성자 함수는 객체가 생성되는 시점에 오직 한 번만 실행된다

- 생성자 함수의 이름은 클래스 이름과 동일하게 작성되어야 한다

- 생성자 함수의 원형에 리턴 타입을 선언하지 않는다

- 생성자 함수는 함수 실행을 종료하기 위해 return 문을 사용할 수 있으나 어떤 값도 리턴하면 안 된다.

- 생성자는 중복 가능하다 (그러려면 매개 변수 개수나 타입이 서로 다르게 선언되어야 한다)

ex) 생성자가 2개

#include <iostream>
using namespace std;
class Circle{
    public:
        int radius;
        Circle(); //기본 생성자 
        Circle(int r); //매개 변수 있는 생성자
        double getArea();
};

Circle::Circle(){
    radius = 1;
    cout << "반지름: " << radius << " 원 생성"<<"\n";
}

Circle::Circle(int r){
    radius = r;
    cout << "반지름: " << radius << " 원 생성"<<"\n";
}

double Circle::getArea(){
    return 3.14*radius*radius;
}
int main() {
    Circle donut; //기본 생성자 호출
    double area = donut.getArea();
    cout<< "donut 면적은 " << area << "\n";
    
    Circle pizza(30); //매개 변수 있는 생성자 호출, 30이 r에 전달됨 
    area = pizza.getArea();
    cout << "pizza 면적은 " << area << "\n";
}

 

위임 생성자 : 객체를 초기화하는 비슷한 코드가 중복된다.

Circle::Circle(){
    radius = 1;
    cout << "반지름: " << radius << " 원 생성"<<"\n"; //중복
}

Circle::Circle(int r){
    radius = r;
    cout << "반지름: " << radius << " 원 생성"<<"\n"; //중복 
}

이를 해결하기 위해 중복된 초기화 코드를 하나의 생성자로 몰고 다른 생성자에서 이 생성자를 호출할 수 있게 함

Circle::Circle() : Circle(1){} //위임 생성자, 호출하여 r에 1을 전달 

Circle::Circle(int r){ //타겟 생성자
    radius = r;
    cout << "반지름: " << radius << " 원 생성"<<"\n";
}

 

클래스의 멤버 변수는 생성자에서 초기화 한다.

- 생성자 서두에 초깃값으로 초기화가 가능하다

#include <iostream>
using namespace std;
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(int a): x(a+100), y(100) {}

예제 3-5)

#include <iostream>
using namespace std;
class Point{
    int x,y;
    public:
        Point();
        Point(int a, int b);
        void show() {
            cout << "(" << x<<","<<y<<")"<<"\n";}
};

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();
}

 

생성자는 무조건 존재한다.

생성자를 만들지 않은 클래스에 대해서는 기본 생성자를 만들어 삽입한다.

기본 생성자 : 클래스에 선언된 어떤 생성자도 없을 때 컴파일러가 자동으로 생성하는 생성자 (=디폴트 생성자), 매개 변수가 없음

class Circle{
      Circle(); //기본 생성자
};

생성자가 하나라도 선언된 클래스의 경우, 컴파일러는 기본 생성자를 자동 삽입하지 않는다.

예제 3-6)

#include <iostream>
using namespace std;
class Rectangle{
    int x,y;
    public:
        Rectangle();
        Rectangle(int a, int b);
        Rectangle(int c);
        bool isSquare();
};

Rectangle::Rectangle(): Rectangle(1,1){}
Rectangle::Rectangle(int a, int b): x(a), y(b) {}
Rectangle::Rectangle(int c): x(c), y(c){}

bool Rectangle::isSquare(){
    if (x==y)
        return true;
    else
        return false;
}

//이렇게 초기화도 가능
int main(){
        Rectangle rect1;
        Rectangle rect2(3,5);
        Rectangle rect3(3);
        
        if(rect1.isSquare())
            cout<<"rect1은 정사각형이다"<<"\n";
        if(rect2.isSquare())
            cout<<"rect2는 정사각형이다"<<"\n";
        if(rect3.isSquare())
            cout<<"rect3는 정사각형이다"<<"\n";
}

 

 

 

3.5 소멸자

객체가 소멸되면 객체 메모리는 시스템으로 반환되고, 소멸자 함수가 실행된다

소멸자 : 객체가 소멸되는 시점에서 자동으로 호출되는 클래스의 멤버 함수

특징

- 객체가 소멸할 때 동적으로 할당받은 메모리를 운영체제에게 돌려주는 등 객체가 사라지기 전에 필요한 조치를 하기 위해

- 소멸자 이름은 클래스 이름 앞에 ~를 붙인다

- 리턴 타입이 없고, 오직 한 개만 존재하며 매개 변수를 가지지 않는다

- 소멸자가 선언되어 있지 않으면 기본 소멸자가 자동으로 생성된다

class Circle{
      Circle(); //기본 생성자
      Circle(int r);
      
      ~Circle(); //소멸자는 오직 하나만 존재, 리턴 없고 매개 변수도 없음
};

Circle::~Circle(){
} //소멸자 함수 구현

소멸자 실행

main() 실행시 donut, pizza의 순서대로 객체가 생성되며, return 0; 이 실행되면 생성된 반대 순으로 pizza, donut 객체가 소멸된다. pizza 객체의 ~Circle() 소멸자와 donut 객체의 ~Circle() 소멸자가 각각 순서대로 실행된다

class Circle{
      Circle(); //기본 생성자
      Circle(int r);
      
      ~Circle(); //소멸자는 오직 하나만 존재, 리턴 없고 매개 변수도 없음
};

Circle::~Circle(){
} //소멸자 함수 구현

int main() {
    Circle donut; 
    Circle pizza(30);
    return 0;
}

예제 3-7)

#include <iostream>
using namespace std;
class Circle{
    public:
        int radius;
        Circle(); 
        Circle(int r); 
        double getArea();
        ~Circle(); //소멸자
};

Circle::Circle(){
    radius = 1;
    cout << "반지름: " << radius << " 원 생성"<<"\n";
}

Circle::Circle(int r){
    radius = r;
    cout << "반지름: " << radius << " 원 생성"<<"\n";
}

Circle::~Circle(){
    cout << "반지름: " << radius << " 원 소멸"<<"\n";
}

double Circle::getArea(){
    return 3.14*radius*radius;
}
int main() {
    Circle donut; 
    Circle pizza(30);
    // return 0; main() 함수는 예외적으로 return 0; 생략 가능 (2장 내용 참고)
}

 

생성자/소멸자 실행 순서

함수 내에서 선언된 객체를 지역 객체, 함수 바깥에 선언된 객체를 전역 객체라고 한다

지역 객체 : 함수가 실행될 때 생성, 함수가 종료할 때 소멸

전역 객체 : 프로그램이 로딩될 때 생성되고 main() 이 종료한 뒤 프로그램 메모리가 사라질 때 소멸된다

Class Circle{
    ...
};

Circle globalCircle; // 전역 객체
void f(){
    Circle localCircle; //지역 객체
}

지역 객체, 전역 객체 모두 생성된 순서의 반대순으로 소멸된다

예시 실행 시

로딩하면 globalDonut > globalPizza 순으로 생성된 후 main() 함수가 실행되면 mainDonut > mainPizza 순으로 생성되고,

main()이 종료되면 mainPizza > mainDonut 순으로 소멸하고, 프로그램이 종료되면 globalPizza > globalDonut 순으로 소멸된다

#include <iostream>
using namespace std;
class Circle{
    public:
        int radius;
        Circle(); 
        Circle(int r); 
        ~Circle(); //소멸자
};

Circle::Circle(){
    radius = 1;
    cout << "반지름: " << radius << " 원 생성"<<"\n";
}

Circle::Circle(int r){
    radius = r;
    cout << "반지름: " << radius << " 원 생성"<<"\n";
}

Circle::~Circle(){
    cout << "반지름: " << radius << " 원 소멸"<<"\n";
}

Circle globalDonut(1000);
Circle globalPizza(2000);
int main() {
    Circle mainDonut; 
    Circle mainPizza(30);
}

 

 

 

3.6 접근 지정 

객체를 캡슐화, 외부에서 접근 가능한 공개 멤버와 외부의 접근을 허용하지 않는 비공개 멤버를 구분

3가지 멤버 접근 지정자

- private

- public

- protected

접근 지정은 클래스 선언부에서 접근 지정자 다음에 콜론을 찍고 멤버들을 선언

멤버 변수는 private로 지정, 생성자는 public으로 지정하는 것이 바람직함

class sample{
    private:
        int a; //클래스 내의 멤버 함수들에게만 접근이 허용 
    public:
        int b; //클래스 내외를 막론하고 프로그램의 모든 함수들에게 접근이 허용
    protected:
        int c; //클래스 내의 멤버 함수와 클래스를 상속받은 파생 클래스의 멤버 함수에게만 접근이 허용
}

 

 

 

3.7 인라인 함수

함수의 호출과 실행을 마치고 돌아오는 과정에서 시간 소모가 발생한다 

함수 호출 오버헤드에서 시간이 무시할 수 없는 비중을 차지하는 경우도 있다

짧은 코드를 함수로 만들면, 함수 호출의 오버헤드가 상대적으로 커서 프로그램 실행 시간이 길어지는 원인이 된다

인라인 함수 : 짧은 코드로 구성된 함수에 대해 실행 속도 저하를 막기 위해 도입된 기능이다

컴파일러는 인라인 함수를 호출하는 곳에 인라인 함수의 코드를 그대로 삽입하여 함수 호출이 일어나지 않게 한다 > 실행시간 빨라짐

장점 : 작은 함수를 인라인으로 선언하면 프로그램의 실행 속도를 향상시킬 수 있다

단점 : 호출 하는 곳에 여러 군데 있으면 그만큼 전체 크기가 늘어난다

제약 : 컴파일러에게 주는 요청이지 강제 명령이 아니다. 따라서 크기나 효율을 따져 불필요한 경우 선언을 무시할 수도 있다.

재귀 함수, static 변수, 반복문, switch문, goto문 등을 가진 함수는 인라인 함수로 허용하지 않는다

inline int odd(int x){
    return (x%2);
}

멤버 함수의 인라인 선언과 자동 인라인

- 생성자를 포함하여 클래스의 모든 멤버 함수가 인라인으로 선언 가능

- 멤버 함수의 크기가 작은 경우 클래스의 선언부에 직접 구현해도 상관 없다

- 클래스의 선언부에 구현된 멤버 함수들에 대해 인라인 선언이 없어도 인라인 함수로 자동 처리

class Circle{
    private:
        int radius;
    public:
    Circle(){
        radius = 1; //자동 인라인 함수 
    }
    
    Circle (int r);
    double getArea(){
        return 3.14*radius*radius;
        //자동 인라인 함수
    }
};

 

 

 

3.8 C++ 구조체 선언

C언어와의 호환성을 위해 구조체를 지원

클래스와 동일한 구조와 기능

struct structName{
    private:
    public:
    protected:
}

객체 생성

structName stObj; //구조체 객체 생성

클래스와 구조체의 차이점

완전히 동일하나,

클래스 디폴트 접근 지정이 private인 반면 구조체의 디폴트 접근 지정은 public이다

 

 

 

3.9 바람직한 C++ 프로그램 작성법

헤더 파일과 cpp 파일을 분리 작성

- 클래스마다 선언부는 헤더파일에, 구현부는 cpp 파일에 분리하여 작성

- main() 등 함수나 전역 변수는 한 개 이상의 cpp 파일에 나누어 작성

>> 전체 프로그램을 관리하기 쉽고 클래스를 재사용하기 쉽다

+) C++ 컴파일러는 cpp 파일들만 컴파일하며 헤더 파일만 따로 컴파일하지는 않는다

헤더 파일을 중복 include 할 때 생기는 문제 해결 방법

#ifndef CIRCLE_H //조건 컴파일문. 여러번 헤더 파일을 include해도 문제가 없게 하기 위해. 
//조건 컴파일러 문의 상수(CIRCLE_H) 는 다른 컴파일 상수와 충돌을 피하기 위해 클래스 이름으로 하는 게 좋음
#define CIRCLE_H 
class Circle{
    private:
        int radius;
    public:
        Circle(); 
        Circle(int r); 
        double getArea();
};

#endif //조건 컴파일문. 여러번 헤더 파일을 include해도 문제가 없게 하기 위해

예제 3-11)

Adder.h 파일 

#ifndef ADDER_H
#define ADDER_H

class Adder{
    int op1, op2;
    public:
        Adder(int a, int b);
        int process();
};

#endif

Adder.cpp 파일

#include <Adder.h>

Adder::Adder(int a, int b){
    op1 = 1; op2 = b;
}
int Adder::process(){
    return op1+op2;
}

Calculator.h 파일

#ifndef CALCULATOR_H
#define CALCULATOR_H

class Calculator{
    public:
        void run();
};

#endif

Calculator.cpp 파일

#include <iostream>
using namespace std

#include <Calculator.h>
#include <Adder.h>

void Calculator::run(){
    cout << "두 수를 입력하세요>>";
    int a, b;
    cin >> a >> b;
    Adder adder(a,b);
    cout << adder.process();
}

main.cpp

#include "Calculator.h"

int main(){
    Calculator calc;
    calc.run();
}

 

 

 

openchallenge

Exp.h 파일

#ifndef EXP_H
#define EXP_H

class Exp{
	int x, y;
    public:
        Exp(int a, int b);
        Exp(int c);
        Exp();
        int getValue();
        int getBase();
        int getExp();
        bool equals(Exp b);
};

#endif

Exp.cpp 파일 

#include <Exp.h>
#include <cmath>
Exp::Exp(int a, int b){
    x = a;
    y = b;
}
Exp::Exp(int c){
    x = c;
    y = 1;
}

Exp::Exp(){
    x = 1;
    y = 1;
}
int Exp::getValue(){
    int result;
    result = pow(x,y);
    return result;
}
int Exp::getBase(){
    return x;
}
int Exp::getExp(){
    return y;
}
bool Exp::equals(Exp b){
    if (getValue() == b.getValue())
        return true;
    else
        return false;
}

main.cpp 파일 

#include <iostream>
using namespace std;

#include "Exp.h"

int main() {
	Exp a(3, 2);
	Exp b(9);
	Exp c;

	cout << a.getValue() << ' ' << b.getValue() << ' ' << c.getValue() << endl;
	cout << "a의 베이스 " << a.getBase() << ',' << "지수 " << a.getExp() << endl;

	if( a.equals(b) )
		cout << "same" << endl;
	else 
		cout << "not same" << endl;
}

 

 

 

연습문제

1

#include <iostream>
using namespace std;

class Tower {
    int height;
    public:
        Tower() {height = 1;}
        Tower(int a) {height = a;}
        int getHeight() {return height;}
};

int main() {
    Tower myTower;
    Tower seoulTower(100);
    cout << "높이는 " << myTower.getHeight() << "미터" << "\n";
    cout << "높이는 " << seoulTower.getHeight() << "미터" << "\n";
}

2

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

class Date {
    int year, month, day;
    public:
        Date(string s) {
        year=stoi(s);
		int n = s.find('/'); 
		month = stoi(s.substr(n + 1));
		n = s.find('/', n + 1);
		day = stoi(s.substr(n + 1));
        }
        Date(int a, int b, int c) {
            year = a;
            month = b;
            day = c;
        }
        void show() {
            cout << year <<"년" << month << "월" << day << "일\n";}
        int getYear(){
            return year;
        }
        int getMonth(){
            return month;
        }
        int getDay(){
            return day;
        }
};

int main() {
    Date birth(2014, 3, 20);
	Date independenceDay("1945/8/15");
	independenceDay.show();
	cout << birth.getYear() << ',' << birth.getMonth() << ',' << birth.getDay() << "\n";
}

3

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

class Account{
    string name;
    int id;
    int money;
    public :
        Account(string s, int a, int b){
            name = s;
            id = a;
            money = b;
        }
    void deposit (int c){
        money += c;
    }
    string getOwner(){
        return name;
    }
    int inquiry(){
        return money;
    }
    int withdraw(int d){
        money = money - d;
        return money;
    }
};
int main() {
    Account a("kitae", 1, 5000);
	a.deposit(50000);
	cout << a.getOwner() << "의 잔액은 " << a.inquiry() << "\n";
	int money = a.withdraw(20000);
	cout << a.getOwner() << "의 잔액은 " << a.inquiry() << "\n";
}

4

#include <iostream>
using namespace std;

class CoffeeMachine{
    int coffee;
    int water;
    int sugar;
    public :
        CoffeeMachine(int a, int b, int c){
            coffee = a;
            water = b;
            sugar = c;
        }
    void drinkEspresso(){
        coffee = coffee - 1;
        water = water - 1;
    }
    void show(){
        cout<<"커피 머신 상태, 커피:"<<coffee<<"\t물:"<<water<<"\t설탕:"<<sugar<<"\n";
    }
    void drinkAmericano(){
        coffee = coffee - 1;
        water = water - 2;
    }
    void drinkSugerCoffee(){
        coffee = coffee - 1;
        water = water - 2;
        sugar = sugar - 1;
    }
    
    void fill(){
        coffee = 10;
        water = 10;
        sugar = 10;
    }
};
int main() {
    CoffeeMachine java(5, 10, 3);
	java.drinkEspresso();
	java.show();
	java.drinkAmericano();
	java.show();
	java.drinkSugerCoffee();
	java.show();
	java.fill();
	java.show();
}

5

#include <iostream>
#include <cstdlib>
#include <ctime>
using namespace std;

class Random{
    public:
        int next(){
            srand((unsigned int)time(0));
            int n1 = rand();
	        return n1;
        }
        int nextInRange(int start, int end){
            srand((unsigned int)time(0));
            int n2 = rand() % (end - start + 1) + start;
	        return n2;
        }
};
int main() {
    Random r;
	cout << "-- 0에서 " << RAND_MAX << "까지의 정수 10개--" << endl;
	for (int i = 0; i < 10; i++) {
		int n = r.next();
		cout << n << ' ';
	}
	cout << endl << endl << "-- 2에서 4까지의 랜덤 정수 10개 --" << endl;
	for (int i = 0; i < 10; i++) {
		int n = r.nextInRange(2, 4);
		cout << n << ' ';
	}
	cout << endl;
}

6

#include <iostream>
#include <cstdlib>
#include <ctime>
using namespace std;

class Random{
    public:
        int next(){
            int n;
	        do {
		        n = rand();
	        } while (n % 2 == 1);
	        return n;
        }
        int nextInRange(int start, int end){
            int n;
            do {
		        n = rand() % (end - start + 1) + start;
	        } while (n % 2 == 1);
	        return n;
        }
};
int main() {
    Random r;
	cout << "-- 0에서 " << RAND_MAX << "까지의 정수 10개--" << endl;
	for (int i = 0; i < 10; i++) {
		int n = r.next();
		cout << n << ' ';
	}
	cout << endl << endl << "-- 2에서 10까지의 랜덤 정수 10개 --" << endl;
	for (int i = 0; i < 10; i++) {
		int n = r.nextInRange(2, 10);
		cout << n << ' ';
	}
	cout << endl;
}

7

#include <iostream>
#include <cstdlib>
#include <ctime>
using namespace std;

class Random{
    public:
        int nextEven();
	    int nextOdd();
	    int nextEvenInRange(int start, int end);
	    int nextOddInRange(int start, int end);
};

int Random::nextEven(){
    int n;
	do {
	   n = rand();
	} while (n % 2 == 1);
	return n;
}

int Random::nextOdd(){
    int n;
	do {
	    n = rand();
	} while (n % 2 == 0);
	return n;
}

int Random::nextOddInRange(int start, int end){
    int n;
	do {
	   n = rand() % (end - start + 1) + start;
	} while (n % 2 == 0);
	return n;
}

int Random::nextEvenInRange(int start, int end){
    int n;
	do {
	   n = rand() % (end - start + 1) + start;
	} while (n % 2 == 1);
	return n;
}

int main() {
    Random r;
	cout << "-- 0에서 " << RAND_MAX << "까지의 짝수 랜덤 정수 10개--" << endl;
	for (int i = 0; i < 10; i++) {
		int n = r.nextEven();
		cout << n << ' ';
	}
	cout << endl << endl << "-- 2에서 9까지의 홀수 랜덤 정수 10개 --" << endl;
	for (int i = 0; i < 10; i++) {
		int n = r.nextOddInRange(2, 9);
		cout << n << ' ';
	}
	cout << endl;
}

8

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

class Integer{
    int n;
    public:
        Integer(int a){
            n=a;
        }
        int get();
        void set(int b);
        Integer(string s){
            n = stoi(s);
        }
        bool isEven();
};

int Integer::get(){
    return n;
}
void Integer::set(int b){
    n=b;
}
bool Integer::isEven(){
    if (n%2==1)
        return 1;
    else
        return 2;
}

int main() {
    Integer n(30);
	cout << n.get() << ' ';
	n.set(50);
	cout << n.get() << ' ';

	Integer m("300");
	cout << m.get() << ' ';
	cout << m.isEven();
}

9

 

#include <iostream>
using namespace std;

class Oval{
    int width, height;
    public:
        Oval();
        Oval(int a, int b);
        void set(int c, int d);
        void show();
        int getWidth();
        int getHeight();
        ~Oval();
};

Oval::Oval() {
    width = 1;
    height = 1;
}
Oval::Oval(int a, int b) {
    width = a;
    height = b;
}

void Oval::set(int c, int d){
    width = c;
    height = d;
}

int Oval::getWidth(){
    return width;
}

int Oval::getHeight(){
    return height;
}

void Oval::show(){
    cout<<"width = "<<width<<", height = "<<height<<"\n";
}

Oval::~Oval(){
    cout<<"Oval 소멸 : width = "<<width<<", height = "<<height<<"\n";
}

int main() {
    Oval a, b(3, 4);
	a.set(10, 20);
	a.show();
	cout << b.getWidth() << "," << b.getHeight() << endl;
}

10

(1)

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

class Add {
	int a, b;
    public:
	    void setValue(int x,int y);
	    int calculate();
};

class Sub {
	int a, b;
    public:
	    void setValue(int x,int y);
	    int calculate();
};

class Mul {
	int a, b;
    public:
	    void setValue(int x,int y);
	    int calculate();
};

class Div {
	int a, b;
    public:
	    void setValue(int x,int y);
	    int calculate();
};

void Add::setValue(int x,int y){ a=x; b=y; }
int Add::calculate(){ return a+b; }
void Sub::setValue(int x,int y){ a=x; b=y; }
int Sub::calculate(){ return a-b; }
void Mul::setValue(int x,int y){ a=x; b=y; }
int Mul::calculate(){ return a*b; }
void Div::setValue(int x,int y){ a=x; b=y; }
int Div::calculate(){ return a/b; }

int main() {
    Add a;
	Sub s;
	Mul m;
	Div d;
	while (true) {
		cout << "두 정수와 연산자를 입력하세요>>";
		int x, y;
		char op;
		cin >> x >> y >> op;

		switch (op) {
		case '+':
			a.setValue(x, y);
			cout << a.calculate() << endl;
			break;
		case '-':
			s.setValue(x, y);
			cout << s.calculate() << endl;
			break;
		case '*':
			m.setValue(x, y);
			cout << m.calculate() << endl;
			break;
		case '/':
			d.setValue(x, y);
			cout << d.calculate() << endl;
			break;
		default:
			break;
		}
	}
}

(2)

Cal.h

#ifndef CAL_H
#define CAL_H

class Add {
	int a, b;
    public:
	    void setValue(int x,int y);
	    int calculate();
};

class Sub {
	int a, b;
    public:
	    void setValue(int x,int y);
	    int calculate();
};

class Mul {
	int a, b;
    public:
	    void setValue(int x,int y);
	    int calculate();
};

class Div {
	int a, b;
    public:
	    void setValue(int x,int y);
	    int calculate();
};
#endif

cal.cpp

#include <iostream>
#include <string>
#include "calculator.h"

void Add::setValue(int x,int y){ a=x; b=y; }
int Add::calculate(){ return a+b; }
void Sub::setValue(int x,int y){ a=x; b=y; }
int Sub::calculate(){ return a-b; }
void Mul::setValue(int x,int y){ a=x; b=y; }
int Mul::calculate(){ return a*b; }
void Div::setValue(int x,int y){ a=x; b=y; }
int Div::calculate(){ return a/b; }

int main() {
    Add a;
	Sub s;
	Mul m;
	Div d;
	while (true) {
		cout << "두 정수와 연산자를 입력하세요>>";
		int x, y;
		char op;
		cin >> x >> y >> op;

		switch (op) {
		case '+':
			a.setValue(x, y);
			cout << a.calculate() << endl;
			break;
		case '-':
			s.setValue(x, y);
			cout << s.calculate() << endl;
			break;
		case '*':
			m.setValue(x, y);
			cout << m.calculate() << endl;
			break;
		case '/':
			d.setValue(x, y);
			cout << d.calculate() << endl;
			break;
		default:
			break;
		}
	}
}

11

#ifndef BOX_H
#define BOX_H

class Box {
	int width, height;
	char fill;
	public:
	    Box(int w, int h);
	    void setFill(char f);
	    void setSize(int w, int h);
	    void draw();
};

#endif

Box.cpp

#include <iostream>
#include "Box.h"
using namespace std;

Box::Box(int w, int h) { setSize(w, h); fill = '*'; }
void Box::setFill(char f) {fill = f;}
void Box::setSize(int w, int h) {width = w, height = h}
void Box::draw() {
	for (int i = 0; i < height; i++) {
		for (int j = 0; j < width; j++) {
			cout << fill;
		}
		cout << endl;
	}
}

main.cpp

#include "Box.h"

int main() {
	Box b(10, 2);
	b.draw();
	cout << endl;
	b.setSize(7, 4);
	b.setFill('^');
	b.draw();
}

12

#ifndef RAM_H
#define RAM_H

class Ram {
	char mem[100 * 1024];
	int size;
public:
	Ram();
	~Ram();
	char read(int address);
	void write(int address, char value);
};

#endif

Ram.cpp

#include <iostream>
#include <string>
#include "Ram.h"

Ram::Ram(){
    for (int i = 0; i < 100 * 1024; i++) {
		mem[i] = 0;
	}
	size = 100 * 1024;
}
void Ram::write(int address, char value) {
    mem[address] = value;
}
char Ram::read(int address){
    return mem[address];
}
Ram::~Ram(){
    cout << "메모리 제거됨";
}

main.cpp

#include "Ram.h"

int main() {
	Ram ram;
	ram.write(100, 20);
	ram.write(101, 30);
	char res = ram.read(100) + ram.read(101);
	ram.write(102, res);
	cout << "102번지의 값 = " << (int)ram.read(102) << endl;

	return 0;
}