C++. 사원증, 링 Project

lsw·2021년 3월 27일
0

Mini Projects

목록 보기
9/11
post-thumbnail

1. 목적

  • Rings : 클래스 캡슐화 사용
  • Namecard : 생성자 / 소멸자 / enumerating 활용

2. Rings(두 개의 원)

  • 두 원을 반지름(radius)크기 순으로 비교하여 더 작은 원을 inner, 큰 원을 outer circle로 지정하기

원의 구성 요소에는 1. 중심점 2. 반지름 이 있다. 중심점을 변수로 저장할 클래스를 "Point", 중심점과 반지름 모두를 변수로 저장할 클래스를 "Circle", 두 원(Circle)을 변수로 저장할 클래스를 "Ring"으로 지정한다.


2.1. 코드

ring.h

#pragma once
/*Point class*/
class Point // 중심점 [x,y]를 멤버 변수로
{
private: // 정보 은닉
	int x;
	int y;

public: // 외부 참조 가능
	void Init(int num1, int num2); // 생성자 함수(생성자는 아니다!)
	void Show();
};

/*Circle class*/
class Circle
{
private:
	double radius; // 반지름
	Point pos; // 중심점
// Point클래스에 접근할 수 있는 변수 선언
public:
// 생성자 함수
	void Init(int x1, int y1, int rad1);
// 조회
	void Show();
};

/*Ring class*/
class Ring
{
private:
// 두 개의 원을 멤버변수로, Circle클래스 함수 접근
	Circle cir1;
	Circle cir2;

public:
// 생성자 함수
// parameter : Circle1 중심점[x1, y1], 반지름 rad1 / Circle2 중심점[x2, y2], 반지름 rad2
	void Init(int x1, int y1, int rad1, int x2, int y2, int rad2);
// 조회
	void Show();
};

ring.cpp

#include "ring.h" // 헤더파일 참조
#include <iostream>
using namespace std;

/*Point class*/
// 생성자 **함수(거듭 강조하지만 "생성자"는 아니다)**
	void Point::Init(int num1, int num2)
	{
		x = num1;
		y = num2;
	}
// 조회함수(중심점 정보) 
	void Point::Show()
	{
		cout << "[x,y] = " << x << "," << y << endl;
	}

/*Circle class*/
// 생성자 함수
	void Circle::Init(int x1, int y1, int rad1)
	{
		pos.Init(x1, y1); // pos객체를 통해 Point클래스의 생성자 함수 호출, 중심점 초기화
		radius = rad1; // 반지름 초기화
	}
// 조회함수(중심점 / 반지름 정보)
	void Circle::Show()
	{
// 반지름정보
		cout << "radius = " << radius << endl;
// 중심점 정보
		pos.Show();
	}

/*Ring class*/
// 생성자 함수(두 개의 원을 초기화할 parameters)
	void Ring::Init(int x1, int y1, int rad1, int x2, int y2, int rad2)
	{
// let cir1 = inner circle, cir2 = outer circle
		if (rad1 < rad2)
		{
			cir1.Init(x1, y1, rad1); // inner circle
			cir2.Init(x2, y2, rad2); // outer circle
		}
		else
		{
			cir1.Init(x2, y2, rad2); // inner circle
			cir2.Init(x1, y1, rad1); // outerc circle
		}
	}
// 조회함수(두개 원의 정보)
	void Ring::Show()
	{
		cout << "Inner Circle info..." << endl;
		cir1.Show(); // Circle클래스 조회함수 호출
		cout << "Outer Circle info..." << endl;
		cir2.Show();
	}

main.cpp

#include "ring.h"
int main()
{
	Ring ringmabell; // Ring클래스 객체 선언, **public함수** 접근
	ringmabell.Init(5,5,7,4,3,5);
// x1,y1,rad1,x2,y2,rad2 - Ring클래스 생성자 함수 호출을 통해 객체 ringmabell의 멤버변수 초기화
// 조회함수 호출(두 개의 원정보)
	ringmabell.Show();
	return 0;
}

2.2. 결과


3. Namecard(사원증)

  • 사원의 정보를 저장하는 클래스를 만들되 직급을 제외한 변수는 모두 문자열로 선언한다. 또한 default가 아닌 생성자 정의를 통해 멤버변수를 초기화 하고 소멸자를 이용해 동적으로 할당되었던 메모리를 비워라.

생성자와 new-delete구문의 문법을 알아야 한다. 또한 소멸자의 필요성을 이해하고 있을 필요가 있다.


3.1. 코드

namecard.h

#pragma once // 헤더파일 중복 참조 방지
#include<iostream>
using namespace std;

/*COM_POS namespace*/
namespace COM_POS // 특정 문자에 정수의미 부여
{
	enum
	{
		CLERK = 1, SENIOR, ASSIST, MANAGER
	};
}

/*Namecard class*/
class Namecard
{
// 멤버변수
private:
	char* Name; // 사원명
	char* Cname; // 회사명
	char* Phone; // 전화번호
	int Rank; // 직급

// 멤버함수
public:
// 생성자
	Namecard(const char* name, const char* cname, const char* phone, int num);
/* 문자열 **매개변수 - 입력인자** 선택지
1. 매개변수 : char str[] - 입력인자 : (const)"string"
2. 매개변수 : char * str - 입력인자 : (const)"string"
3. 매개변수 : const char str[] - 입력인자 : "string"
4. 매개변수 : const char * str - 입력인자 : "string"
*/
// 직원정보 조회함수
	void Show();
// 소멸자
	~Namecard() // 동적할당공간 비움
	{
// 문자열 소멸
		delete []Name;
		delete []Cname;
		delete []Phone;
		cout << "Destructed!" << endl; // 소멸자 정상 호출 확인
	}
};

namecard.cpp

#include "namecard.h" // 헤더파일 참조
#include<iostream>
#include<cstring>
using namespace std;

/*생성자*/
Namecard::Namecard(const char* name, const char* cname, const char* phone, int num)
/*
rank 매개변수 자리가 정수형(int) 이니 정수의미를 갖는 문자를 인자로 입력한다
(namespace::char = int)
*/
{
// 사원명
	int len1 = strlen(name) + 1; // 입력 문자 길이 + '\n'공간 1
	Name = new char[len1]; // 동적할당
	strcpy_s(Name, len1, name); // 컴파일러에 따라 strcpy함수의 활용이 상이할 수 있음
// 회사명
	int len2 = strlen(cname) + 1;
	Cname = new char[len2]; // 동적할당
	strcpy_s(Cname,len2, cname);
// 전화번호
	int len3 = strlen(phone) + 1;
	Phone = new char[len3]; // 동적할당
	strcpy_s(Phone, len3, phone);
// 직급
	Rank = num;
}

/*직원정보 조회함수*/
void Namecard::Show()
{
	cout << "이름 : " << Name << endl;
	cout << "회사명 : " << Cname << endl;
	cout << "전화번호 : " << Phone << endl;
// 입력되는 **정수에 따라 다른 직급** 출력
	switch(Rank) // ex) COM_POS::MANAGER = 4
	{
	case 1:
	{
		cout << "직급 : " << "사원" << endl;
		break;
	}
	case 2:
	{
		cout << "직급 : " << "과장" << endl;
		break;
	}
	case 3:
	{
		cout << "직급 : " << "차장" << endl;
		break;
	}
	case 4:
	{
		cout << "직급 : " << "부장" << endl;
		break;
	}
 }
	cout << endl;
}

main.cpp

#include "namecard.h"

int main()
{
// Namecard 객체 생성
	Namecard man_Clerk("이상원", "NAVER", "010-1234-5678", COM_POS::CLERK);
	Namecard man_Assist("김윤수", "SAMSUNG Electronics", "010-9876-5432", COM_POS::ASSIST);
	Namecard man_Manager("백규현", "Kakao", "010-4535-3543", COM_POS::MANAGER);
// Namecard 클래스 멤버함수 호출(접근)
	man_Clerk.Show(); // 조회1
	man_Assist.Show(); // 조회2
	man_Manager.Show(); // 조회3
	return 0;
}

3.2. 결과


3.3. 결론

  1. string(문자열)을 인자로 받아들이기 위한 매개변수형 - 인자형 조합이 다양하게 존재한다.
  • char str[] - const("string")
  • const char str[] - "string"
  • char * str - const("string")
  • const char * str - "string"
  1. 생성자에서 이니셜라이저 를 이용한 멤버변수 초기화는 변수를 선언과 동시에 정의함으로써 기능적 우월성을 동반한다. 이러한 측면 뿐만 아니라 참조자const 상수화 변수는 선언과 동시에 초기화 해주어야 하기 대문에 이니셜라이저를 이용하여 초기화를 해줘야만 한다. 이 경우 본문에서의 초기화는 에러를 발생시킨다.
// 생성자에서 본문을 이용한 멤버변수 초기화(비유)
int num;
num = 3;
// 생성자에서 이니셜라이저를 이용한 멤버변수 초기화(비유)
int num = 3;

// ex) 참조자 초기화
class Classname
{
  char & str_ref;
  int phone;
  public:
  Classname (int num, const char & str)
: str_ref(str) // 이처럼 참조자의 초기화는 이니셜라이저를 이용해야만 한다.
{
  phone = num;
}
  1. new - delete는 같이 사용하는것이 바람직하다. (그렇다고 소멸하지 않은 상태에서 종료 후 재시작 시 동적할당된 메모리가 잔존해 있는 것은 아니다.)

  2. private / public 으로 멤버의 접근 정도에 차등을 둬 유동성을 부여한다. but 정보은닉의 관점에서 멤버변수만큼은 private접근성으로 제한하는 것을 지향한다.

profile
미생 개발자

0개의 댓글