본문 바로가기

C++ 프로그래밍 (1학년 2학기)

231130 C++프로그래밍 13주차

1. C++에서 private과 protected의 접근 속성 공통점과 차이점

[공통점]
'private'과 'protected' 키워드 둘 다 클래스 외부에서의 접근을 제한한다.

이는 클래스의 내부 구조를 보호하고, 데이터의 무분별한 변경을 막는 등의 역할을 한다.
[차이점]
'private' : 이 키워드가 붙은 멤버 변수나 함수는 그 클래스 내부에서만 접근이 가능하다. 따라서 해당 클래스의 인스턴스를 통해서도 접근할 수 없다. 이를 통해 클래스의 내부 데이터를 완전히 캡슐화 할 수 있다.
'protected' : 이 키워드가 붙은 멤버 변수나 함수는 그 클래스 내부 및 상속받은 클래스에서 접근이 가능하다. 이는 상속 관계에서 부모 클래스의 멤버 변수나 함수를 자식 클래스에서 재사용할 필요가 있을 때 유용하다.

2. 

#include <iostream>
using std::cout;
using std::endl;
class A1 // 아버지
{
	int a;
public:
	A1(int i) { a = i; }
	int getA() { return a; }
};
class A2 // 어머니
{
	int b;
public:
	A2(int i) { b = i; }
	int getB() { return b; }
};
class B :public A1, public A2
{
	// 기본 클래스 A1과 A2로부터
	// 상속 받은 파생 클래스
	int c;
public:
	B(int i, int j, int k) :A1(i), A2(j) { c = k; }
	// i는 기본클래스 A1의 생성자로,
	// j는 기본클래스 A2의 생성자로
	// 각각 매개변수 전달
	void show() {
		cout << getA() << ' ' << getB() << ' ' << c << endl;
	}
};
int main()
{
	B bb(1, 2, 3);
	bb.show();
	return 0;
}

3. 

#include <iostream> 
using std::cout; 
using std::endl; 

class B1 { // 'B1'이라는 클래스를 선언합니다. 이 클래스는 아버지 역할을 합니다.
	double d; // private 멤버 변수 'd'를 선언합니다.
public: // 이후로 선언되는 멤버들은 public입니다.
	B1(double dd) { d = dd; } 
    // B1 클래스의 생성자를 선언하고, 매개변수로 받은 dd를 멤버 변수 d에 할당합니다.
	double getD() { return d; } // d 값을 반환하는 getter 함수를 선언합니다.
};

class B2 { // 'B2'라는 클래스를 선언합니다. 이 클래스는 어머니 역할을 합니다.
	int i; // private 멤버 변수 'i'를 선언합니다.
public: // 이후로 선언되는 멤버들은 public입니다.
	B2(int ii) { i = ii; } 
    // B2 클래스의 생성자를 선언하고, 매개변수로 받은 ii를 멤버 변수 i에 할당합니다.
	int getI() { return i; } // i 값을 반환하는 getter 함수를 선언합니다.
};

class D :public B1, public B2 { 
// 'D'라는 클래스를 선언하고, B1과 B2 클래스를 public으로 상속받습니다.
	char c; // private 멤버 변수 'c'를 선언합니다.
public: // 이후로 선언되는 멤버들은 public입니다.
	D(double dd, int ii, char cc) :B1(dd), B2(ii) 
    // D 클래스의 생성자를 선언하고, B1과 B2의 생성자를 초기화 리스트를 통해 초기화합니다.
	{
		c = cc; // 매개변수로 받은 cc를 멤버 변수 c에 할당합니다.
	}
	void print() { // 멤버 변수들의 값을 출력하는 함수를 선언합니다.
		cout << "Double : " << getD() << endl; 
        // B1의 멤버 함수인 getD()를 호출하여 d의 값을 출력합니다.
		cout << "Int : " << getI() << endl; 
        // B2의 멤버 함수인 getI()를 호출하여 i의 값을 출력합니다.
		cout << "Char : " << c << endl; // 멤버 변수 c의 값을 출력합니다.
	}
};

int main() // 메인 함수를 선언합니다.
{
	D d(1.23, 10, 'H'); 
    // D 클래스의 객체 d를 생성하고, 생성자에 필요한 매개변수를 전달합니다.
	cout << d.getD() << ',' << d.getI() << endl; 
    // d 객체의 getD(), getI() 멤버 함수를 호출하여 결과를 출력합니다.
	d.print(); // d 객체의 print() 멤버 함수를 호출하여 결과를 출력합니다.
	return 0; // 프로그램을 종료합니다.
}

4. 여러 개의 기본 클래스를 상속 받을 때, 생성자와 소멸자의실행 순서

 - 생성자는 기본 클래스가 지정된 순서대로 왼쪽에서 오른쪽으로 실행되고, 소멸자는 역순으로 실행된다.

#include <iostream>
using std::cout;
class A1 // 기본 클래스 1
{
	int a;
public:
	A1() { cout << "A1의 생성자.\n"; }
	~A1() { cout << "A1의 소멸자.\n"; }
};
class A2 // 기본 클래스 2
{
	int b;
public:
	A2() { cout << "A2의 생성자.\n"; }
	~A2() { cout << "A2의 소멸자.\n"; }
};
class B : public A1, public A2
	// 기본 클래스 1과 2로부터
	// 상속 받은 파생 클래스
{
	int c;
public:
	B() { cout << "B의 생성자.\n"; }
	~B() { cout << "B의 소멸자.\n"; }
};
int main()
{
	B bb;
	return 0;
}

5. 이름과 전화번호를 관리(기본클래스 Name, 파생클래스Phone)

• 출력 결과 : Smile Han의 전화번호는1234-5678

• 상속을 이용하여 기존의 Name 클래스를 재사용할 수 있고, 중복되는 코드는 줄일 수 있다.

#include <iostream>
using std::cout;
#include <string>
class Name { //기본 클래스는 이름만 처리
	std::string name;
public:
	void get_name(std::string s) { name = s; }
	void print_name() { cout << name << "의 전화번호는"; }
};
class Phone : public Name { //파생클래스는 전화번호처리
	std::string phone;
public:
	void get_phone(std::string s) { phone = s; }
	void print_phone() {
		print_name();
		cout << phone;
	}
};
int main()
{
	Phone h;
	h.get_name("Smile Han");
	h.get_phone("1234-5678");
	h.print_phone();
	return 0;
}

6. 5번 소스의 class diagram

 

 

 

7. 수업에서 실습으로 만든 프로그래밍 소스

#include <iostream>
using std::cout;
using std::endl;
using std::string;
class Man {
protected:
	string name;
	int age;
public:
	Man(string name, int age) {
		this->name = name;
		this->age = age;
	}
	void m_show() {
		cout << "이름 : " << name << endl;
		cout << "나이 : " << age << endl;
	}
};
class Student : public Man {
	string ban;
	string hak;
public:
	Student(string n, int a, string b, string h) : Man(n,a) {
		ban = b;
		hak = h;
	}
	void s_show() {
		m_show();
		cout << "반 : " << ban << endl;
		cout << "학번 : " << hak << endl;
	}
};
class Teacher : public Man {
	string major;
	string subject;
public:
	Teacher(string n, int a, string m, string s) : Man(n, a) {
		major = m;
		subject = s;
	}
	void t_show() {
		m_show();
		cout << "전공 : " << major << endl;
		cout << "담당과목 : " << subject << endl;
	}
};


int main()
{
	Student lsy("홍길동", 21, "B반", "200012345");
	Teacher hsh("한미소", 40, "전산", "C++프로그래밍");
	lsy.s_show();
	hsh.t_show();
	return 0;
}

8. 7번 소스의 클래스다이어그램

 

9. 7번 소스를 응용하여 담당교수까지 나타내는 소스

#include <iostream>
using std::cout;
using std::endl;
using std::string;
class Man {
protected:
	string name;
	int age;
public:
	Man(string name, int age) {
		this->name = name;
		this->age = age;
	}
	void m_show() {
		cout << "이름 : " << name << endl;
		cout << "나이 : " << age << endl;
	}
};
class Dam {
protected:
	string name;
	int age;
public:
	Dam(string name, int age) {
		this->name = name;
		this->age = age;
	}
	void m_show() {
		cout << "담당교수의 이름 : " << name << endl;
		cout << "나이 : " << age << endl;
	}
};
class Student : public Man {
	string ban;
	string hak;
public:
	Student(string n, int a, string b, string h) : Man(n,a) {
		ban = b;
		hak = h;
	}
	void s_show() {
		m_show();
		cout << "반 : " << ban << endl;
		cout << "학번 : " << hak << endl;
	}
};
class Teacher : public Man {
	string major;
	string subject;
public:
	Teacher(string n, int a, string m, string s) : Man(n, a) {
		major = m;
		subject = s;
	}
	void t_show() {
		m_show();
		cout << "전공 : " << major << endl;
		cout << "담당과목 : " << subject << endl;
	}
};
class Mteacher : public Dam {
	string major;
	string subject;
public:
	Mteacher(string n, int a, string m, string s) : Dam(n, a) {
		major = m;
		subject = s;
	}
	void mt_show() {
		m_show();
		cout << "전공 : " << major << endl;
		cout << "담당과목 : " << subject << endl;
	}
};


int main()
{
	Student lsy("홍길동", 20, "B반", "200012345");
	Teacher hsh("한미소", 40, "전산", "C++프로그래밍");
	lsy.s_show();
	hsh.t_show();

	Student abc("이길동", 21, "B반", "202312345");
	Mteacher def("교오수", 40, "회계", "C#프로그래밍");
	abc.s_show();
	def.mt_show();
	return 0;
}

10. virtual : 가상의

부모가 만든 함수 앞에 virtual을 쓰면 부모와 자식이 같은 이름의 함수를 만들었을 때 부모가 만든 함수는 가상의 함수 처리가 되어 자식의 함수가 사용된다.

다음 함수를 출력했을 때, virtual이 없다면 출력문에 Dot::draw()이 출력되지만 virtual이 있다면 line함수의 Line::draw()가 호출된다.

#include <iostream>
using std::cout;
class Dot {
public:
	virtual void draw() { cout << "Dot::draw()\n";}
	void print() {
		cout << "Dot 클래스\n";
		draw();
	}
};
class Line :public Dot 
{
public:
	void draw() {	cout <<	"Line::draw()\n";}
};
int main() {
	Line line;
	line.print();
	return 0;
}

11. virtual은 부모에게 쓴다면, override는 자식에게 쓰는 것이다.

위치

- virtual : 함수 앞에 작성

- override : 소괄호 뒤에 작성, 작성하지 않아도 상관없음

#include <iostream>
using std::cout;
class Dot {
public:
	void draw() { cout << "Dot::draw()\n";}
	void print() {
		cout << "Dot 클래스\n";
		draw();
	}
};
class Line :public Dot 
{
public:
	void draw() override {	cout <<	"Line::draw()\n";}
};
int main() {
	Line line;
	line.print();
	return 0;
}

 

 

 

 

참고자료 : 한성현 교수님 수업자료

댓글