연습문제
1번
다음과 같이 2개의 클래스를 정의했을 떄, 위임(delegation)을 사용해서 두 클래스의 set 함수와 print 함수를 정의해주세요.
//First 클래스 선언
class First
{
private:
int a;
public:
void set(int a);
void print() const;
};
//Second 클래스 선언
class Second :public First
{
private:
int b;
public:
void set(int a, int b);
void print() const; };
풀이.
//First 클래스의 메소드 정의
void First::set(int a2)
{
First::a = a2;
}
void First::print() const
{
cout << a;
}
//Second 클래스의 메소드 정의
void Second::set(int a2, int b2)
{
/*상위 클래스의 private 멤버는 하위 클래스에서 접근할 수 없으므로
상위 클래스의 메소드를 위임해 접근하기*/
First::set(a2);
b = b2;
}
void Second::print() const {
First::print();
cout << b;
}
2번
다음과 같은 First 클래스의 정의가 있을 때, First 클래스를 public 상속하는 Second 클래스를 만들었다고 합시다. Second 클래스에서 one, two, set에 대한 접근성(접근할 수 있는지 없는지)이 어떻게 되는지 설명하세요.
class First
{
private:
int one;
protected:
int two;
public:
void set(int one, int two);
}
풀이.
one은 private 멤버이므로 접근할 수 없고,
two는 protected 멤버이므로 파생 클래스인 Second에서 접근할 수 있고,
set은 public 멤버이므로 접근할 수 있다.
3번
다음과 같은 3개의 클래스 정의가 있을 때 생성자와 print 함수를 정의하세요.
//First 클래스 선언
class First
{
private:
int a;
public:
First(int a);
void print() const;
};
//Second 클래스 선언
class Second :public First
{
private:
int b;
public:
Second(int a, int b);
void print() const;
};
class Third :public Second
{
private:
int c;
public:
Third(int a, int b, int c);
void print()const;
};
풀이.
//First 생성자
First::First(int a2)
:a(a2)
{
}
void First::print() const
{
cout << a;
}
//Second 생성자
Second::Second(int a2, int b2)
:First(a2), b(b2)
{
//베이스 클래스의 생성자를 먼저 호출한 후 파생 클래스 멤버 초기화
}
void Second::print() const
{
First::print();
cout << b;
}
//Third 생성자
Third::Third(int a2, int b2, int c2)
:Second(a2, b2), c(c2)
{
}
void Third::print() const
{
Second::print();
cout << c;
}
파생 클래스에서 베이스 클래스 멤버에 접근할 수 없으므로 생성자에서 상속된 private 데이터 멤버에 접근할 수 없어 초기화가 불가능하다.
파생 클래스의 생성자에서 베이스 클래스의 생성자를 호출하고, 소멸자에서 베이스 클래스의 소멸자를 호출하는 형태로 해결할 수 있다.
프로그래밍 문제
1번
정사각형을 나타내는 Square 클래스를 만드세요. Square 클래스는 데이터 멤버로 한 변의 길이를 나타내는 side를 갖습니다. 이어서 둘레를 구하는 getPeri, 넓이를 구하는 getArea라는 멤버 함수를 만드세요. 이어서 Square 클래스를 상속해서, 정육면체를 나타내는 Cube 클래스를 만드세요. Cube 클래스는 추가적인 데이터 멤버가 필요하지 않습니다. 대신 겉넓이를 구하는 getArea와 부피를 구하는 getvolume 멤버 함수를 만드세요. Square 클래스와 Cube 클래스 모두 적절한 생성자와 소멸자를 만드세요.
풀이.
#include <iostream>
using namespace std;
//square 클래스 선언
class Square
{
private:
double side; //한 변의 길이
public:
Square(double s);
~Square();
double getPeri() const; // 둘레 = side * 4
double getArea() const; // 넓이 = side * side
};
//Cube 클래스 선언
class Cube :public Square
{
public:
Cube(double side);
~Cube();
double getArea() const; //겉넓이 = area * 6
double getVolume() const; //부피 = area * side
};
//Square 생성자
Square::Square(double s)
:side(s)
{
}
//Square 소멸자
Square::~Square()
{
}
//Sqaure 메소드
double Square::getPeri() const
{
return side * 4;
}
double Square::getArea() const
{
return side * side;
}
//Cube 생성자
Cube::Cube(double s)
:Square(s)
{
}
//Cube 소멸자
Cube::~Cube()
{
}
//Cube 메소드
double Cube::getArea() const
{
return Square::getArea() * 6;
}
double Cube::getVolume() const
{
return (Square::getPeri() / 4) * Square::getArea();
}
//test
int main()
{
Square square(3);
cout << square.getArea() << endl;
cout << square.getPeri() << endl;
Cube cube(3);
cout << cube.getArea() << endl;
cout << cube.getVolume() << endl;
}
2번
데이터 멤버로 length와 width를 갖는 Rectangle 클래스를 만드세요. 클래스의 생성자와 소멸자를 정의하고, 둘레와 넓이를 구하는 멤버 함수를 만드세요.
이어서 Rectangle 클래스를 상속하고, 추가적인 데이터 멤버로 height를 갖는 상자를 나타내는 Cuboid 클래스를 만드세요. 그리고 Cuboid의 생성자와 소멸자를 정의하고, 겉넓이와 부피를 구하는 멤버 함수를 만드세요.
풀이.
#include <iostream>
using namespace std;
//Rectangle 클래스 정의
class Rectangle
{
private:
int length;
int width;
public:
Rectangle(int len, int wid);
~Rectangle();
int getLength(); //Cuboid에서 활용하기 위한 getter 함수
int getWidth(); //getter함수 2
int getPeri();
int getArea();
};
//Cuboid 클래스 정의
class Cuboid : public Rectangle
{
private:
int height;
public:
Cuboid(int len, int wid, int hei);
~Cuboid();
int getArea();
int getVolume();
};
/*Rectangle 클래스의 멤버 함수 정의*/
//생성자
Rectangle::Rectangle(int len, int wid)
:length(len), width(wid)
{
}
//소멸자
Rectangle::~Rectangle()
{
}
int Rectangle::getLength()
{
return length;
}
int Rectangle::getWidth()
{
return width;
}
//넓이 getArea
int Rectangle::getArea()
{
return length * width;
}
//둘레 getPeri
int Rectangle::getPeri()
{
return (length + width) * 2;
}
/*Cuboid 클래스의 멤버 함수 정의*/
//생성자
Cuboid::Cuboid(int len, int wid, int hei)
:Rectangle(len, wid), height(hei)
{
}
//소멸자
Cuboid::~Cuboid()
{
}
//겉넓이 구하는 getArea
int Cuboid::getArea()
{
return 2 * (getWidth() * getLength() + height * getWidth() + height * getLength());
}
//부피 구하는 getVolume
int Cuboid::getVolume()
{
return getWidth() * getLength() * height;
}
int main()
{
Rectangle rectangle(3, 4);
Cuboid cuboid(3, 4, 5);
cout << "rectangle의 넓이: " << rectangle.getArea() << endl;
cout << "rectangle의 둘레: " << rectangle.getPeri() << endl;
cout << "cuboid의 겉넓이: " << cuboid.getArea() << endl;
cout << "cuboid의 부피: " << cuboid.getVolume() << endl;
return 0;
}
3번
원을 나타내는 Circle 클래스를 만들고, 이를 기반으로 구를 나타내는 Sphere 클래스를 만드세요.
풀이.
Circle.h
#pragma once
class Circle
{
private:
int radius;
public:
Circle(int r);
~Circle();
int getRadius();
double getPeri();
double getArea();
};
Circle.app
#include "Circle.h"
Circle::Circle(int r)
:radius(r)
{
}
Circle::~Circle()
{
}
int Circle::getRadius()
{
return radius;
}
double Circle::getPeri()
{
return 2 * 3.14 * radius;
}
double Circle::getArea()
{
return 3.14 * radius * radius;
}
Sphere.h
#pragma once
#include "Circle.h"
class Sphere : public Circle
{
public:
Sphere(int r);
~Sphere();
double getSurface();
double getVolume();
};
Sphere.app
#include "Sphere.h"
Sphere::Sphere(int r2)
:Circle(r2)
{
}
Sphere::~Sphere()
{
}
double Sphere::getSurface()
{
return 2 * getRadius() * getPeri();
}
double Sphere::getVolume()
{
return (4 / 3) * getRadius() * getArea();
}
test.app
#include <iostream>
#include "Sphere.h"
using namespace std;
int main()
{
Circle circle(5);
Sphere sphere(5);
cout << "원의 둘레: " << circle.getPeri() << endl;
cout << "원의 넓이: " << circle.getArea() << endl;
cout << "구의 겉넓이: " << sphere.getSurface() << endl;
cout << "구의 부피: " << sphere.getVolume() << endl;
return 0;
}
4번
원을 나타내는 Circle 클래스를 기반으로, 원통을 나타내는 Cylinder 클래스를 만드세요, 원 객체에서 높이를 추가하면 원통이 됩니다.
풀이.
원을 만드는 Circle 클래스는 3번에서 만들었으므로 생략.
Cylinder.h
#pragma once
#include "Circle.h"
class Cylinder :public Circle
{
private:
int height;
public:
Cylinder(int r, int h);
~Cylinder();
double getSurface();
double getVolume();
};
Cylinder.app
#include "Cylinder.h"
Cylinder::Cylinder(int r, int h)
:Circle(r), height(h)
{
}
Cylinder::~Cylinder()
{
}
double Cylinder::getSurface()
{
return height * getPeri() + 2 * getArea();
}
double Cylinder::getVolume()
{
return height * getArea();
}
test.app
#include <iostream>
#include "Cylinder.h"
using namespace std;
int main()
{
Circle circle(5);
Cylinder cylinder(5, 10);
cout << "원의 둘레: " << circle.getPeri() << endl;
cout << "원의 넓이: " << circle.getArea() << endl;
cout << "원통의 겉넓이: " << cylinder.getSurface() << endl;
cout << "원통의 부피: " << cylinder.getVolume() << endl;
return 0;
}
5번
직원을 나타내는 Employee 클래스, 그리고 이를 기반으로 하는 월급을 받는 직원을 나타내는 Salaried 클래스, 시급을 받는 직원을 나타내는 Hourly 클래스를 만드세요. 모든 Employee 클래스는 데이터 멤버로 이름(name), 직원 번호(employee number), 생일(birth date), 고용일(date hired)을 갖습니다. 그리고 Salaried 클래스는 월급여(monthly salary)와 연간 보너스(annual bonus)(0~10%의 범위)를 추가로 갖고, Hourly 클래스는 시급(hourly wage)과 초과 근무에 대한 추가 시급 비율(overtime rate)(50~100%의 범위)을 추가로 갖습니다.
풀이.
#include <string>
using namespace std;
class Employee
{
private:
string name;
string employeeNumber;
string birthDate;
string dateHired;
};
class Salaried :public Employee
{
private:
int monthlySalary;
double annualBonus;
};
class Hourly :public Employee
{
private:
int hourlyWage;
double overtimeRate;
};
6번
데이터 멤버로 name과 gpa를 갖는 Student 클래스를 만드세요. 추가적으로 데이터 멤버로 capacity와 학생 배열을 갖는 Course 클래스를 만드세요(학생 배열은 힙 메모리에 선언). Student 클래스에는 학생의 정보를 출력하는 멤버 함수, Course 클래스에는 모든 학생 정보를 출력하는 멤버 함수를 만드세요. capacity는 한 과목을 들을 수 있는 최대 학생 수를 나타냅니다. 학생 수이므로 int 자료형 등으로 선언하세요.
#include <iostream>
#include <string>
using namespace std;
class Student
{
private:
string name;
double gpa;
public:
void printStudentInfo();
};
void Student::printStudentInfo()
{
cout << name << endl;
cout << gpa << endl;
}
class Course
{
private:
int capacity;
Student* pStudents = new Student[capacity];
public:
~Course()
{
delete[]pStudents;
}
void printAllStudentInfo();
};
void Course::printAllStudentInfo()
{
for (int i = 0; i < capacity; i++)
{
pStudents[i].printStudentInfo();
}
}
7번
7번은 명확하게 요구하는 해답이 없는 자율과제이므로 생략하겠습니다.
'프로그래밍 > C, C++' 카테고리의 다른 글
포르잔 C++ 바이블 ch12 연습문제 & 프로그래밍 문제 (0) | 2023.03.05 |
---|---|
[C++]vector를 2차원으로 선언하는 방법 (0) | 2022.12.27 |
[C++] 생성자와 소멸자 (0) | 2022.12.13 |
[C++] 클래스의 구조 (0) | 2022.12.11 |
while 반복문을 종료하는 방법: 센티넬, EOF, 플래그 (0) | 2022.12.10 |