[1번 문제]
/*
Chapter 07에서는 예제 HASComposite.cpp를 통해서 다음의 두 클래스를 정의하였다(완전한 클래스의 정의는 예제 참고)
class Gun
{
....
}
class Police
{
private:
int handcuffs; //소유한 수갑의 수
Gun *pistol; //소유하고 있는 권총
public:
....
}
이에 Police 클래스를 대상으로 깊은 복사가 이뤄지도록 대입 연산자와 복사 생성자를 동시에 정의하고 이의 확인을 위해 main 함수도 적절히 정의해보자
*/
//HasComposite.cpp
/*
#include <iostream>
#include <cstring>
using namespace std;
class Gun
{
private:
int bullet; //장전된 총알의 수
public:
Gun(int bnum) :bullet(bnum)
{
}
void Shot()
{
cout << "BBANG!" << endl;
bullet--;
}
};
class Police
{
private:
int handcuffs; //소유한 수갑의 수
Gun *pistol; //소유하고 있는 권총
public:
Police(int bnum, int bcuff) :handcuffs(bcuff)
{
if (bnum > 0) //이전 예제와 달리 Gun 클래스를 상속하는 것이 아니라, 생성자에서 Gun 객체를 생성해서 이를 참조하고 있다
pistol = new Gun(bnum);
else
pistol = NULL;
}
void PutHandCuff()
{
cout << "SNAP!" << endl;
handcuffs--;
}
void Shot() //Gun 클래스를 상속한다면 별도의 Shot 함수를 정의할 필요가 없다. 그러나 Gun 객체를 멤버변수를 통해 참조하는 구조이기 때문에 이렇게 별도의 함수 정의
{
if (pistol == NULL)
cout << "Hut BBANG!" << endl;
else
pistol->Shot();
}
~Police()
{
if (pistol != NULL)
delete pistol;
}
};
int main(void)
{
Police pman1(5, 3);
pman1.Shot();
pman1.PutHandCuff();
Police pman2(0, 3); //권총을 소유하지 않은 경찰
pman2.Shot();
pman2.PutHandCuff();
return 0;
}
*/
#include <iostream>
#include <cstring>
using namespace std;
class Gun
{
private:
int bullet; //장전된 총알의 수
public:
Gun(int bnum) :bullet(bnum)
{
}
void Shot()
{
cout << "BBANG!" << endl;
bullet--;
}
};
class Police
{
private:
int handcuffs; //소유한 수갑의 수
Gun *pistol; //소유하고 있는 권총
public:
Police(int bnum, int bcuff) :handcuffs(bcuff)
{
if (bnum > 0) //이전 예제와 달리 Gun 클래스를 상속하는 것이 아니라, 생성자에서 Gun 객체를 생성해서 이를 참조하고 있다
pistol = new Gun(bnum);
else
pistol = NULL;
}
Police(Police &ref) :handcuffs(ref.handcuffs) //복사 생성자
{
if (ref.pistol != NULL)
pistol = new Gun(*(ref.pistol));
else
pistol = NULL;
}
Police &operator=(const Police &ref) //대입 연산자
{
cout << "Police& operator=()" << endl; //대입연산자 실행됬다고 출력
handcuffs = ref.handcuffs;
if (pistol != NULL)
delete pistol;
if (ref.pistol != NULL)
pistol = new Gun(*(ref.pistol));
else
pistol = NULL;
return *this;
}
void PutHandCuff()
{
cout << "SNAP!" << endl;
handcuffs--;
}
void Shot() //Gun 클래스를 상속한다면 별도의 Shot 함수를 정의할 필요가 없다. 그러나 Gun 객체를 멤버변수를 통해 참조하는 구조이기 때문에 이렇게 별도의 함수 정의
{
if (pistol == NULL)
cout << "Hut BBANG!" << endl;
else
pistol->Shot();
}
~Police()
{
if (pistol != NULL)
delete pistol;
}
};
int main(void)
{
Police pman1(5, 3);
Police pman2 = pman1; //복사생성자의 호출
pman2.PutHandCuff();
pman2.Shot();
Police pman3(2, 4);
pman3 = pman1; //대입 연산자 호출
pman3.PutHandCuff();
pman3.Shot();
return 0;
}
[2번 문제]
/*
Chapter 07의 문제 07-2의 두번 째 문제에서는 다음의 두 클래스 정의를 요구하였다.
class Book
{
private:
char *title; //책의 제목
char *isbn; //국제표준도서범ㄴ호
int price; //책의 정가
....
};
class EBook :public Book
{
private:
char *DRMKey; //보안관련 키
....
};
이 때 정의한 두 클래스를 대상으로 Book 클래스도, EBook 클래스도 깊은 복사가 진행이 되도록 복사생성자와 대입 연산자를 정의하고,
이의 확인을 위한 main 함수도 적절히 정의해보자.
참고로 이 문제의 해결을 위해서는 여러분이 생각해봐야 할 요소들이 몇 가지 존재한다.
특히 앞서 말한 다음 사실을 완전히 이해한 다음에 이 문제를 해결하기 바란다.
"C++에서, AAA형 참조자는 AAA 객체 또는 AAA를 직접 혹은 간접적으로 상속하는 모든 객체를 참조할 수 있다."
*/
#include <iostream>
#include <cstring>
using namespace std;
class Book
{
private:
char *title; //책의 제목
char *isbn; //국제표준도서번호
int price; //책의 정가
public:
Book(char *booktitle, char *bookisbn, int bookprice) :price(bookprice)
{
title = new char[strlen(booktitle) + 1];
strcpy(title, booktitle);
isbn = new char[strlen(bookisbn) + 1];
strcpy(isbn, bookisbn);
}
Book(const Book &ref) :price(ref.price) //복사 생성자
{
title = new char[strlen(ref.title) + 1];
strcpy(title, ref.title);
isbn = new char[strlen(ref.isbn) + 1];
strcpy(isbn, ref.isbn);
}
Book &operator=(const Book &ref) //대입 연산자
{
cout << "Book &operator=()" << endl; //대입연산자 호출을 출력
delete[]title;
delete[]isbn;
title = new char[strlen(ref.title) + 1];
strcpy(title, ref.title);
isbn = new char[strlen(ref.isbn) + 1];
strcpy(isbn, ref.isbn);
price = ref.price;
return *this;
}
void ShowBookInfo()
{
cout << "제목: " << title << endl;
cout << "ISBN: " << isbn << endl;
cout << "가격: " << price << endl;
}
~Book()
{
delete[]title;
delete[]isbn;
}
};
class Ebook :public Book
{
private:
char *DRMKey; //보안관련 키
public:
Ebook(char *booktitle, char *bookisbn, int bookprice, char *key) :Book(booktitle, bookisbn, bookprice)
{
DRMKey = new char[strlen(key) + 1];
strcpy(DRMKey, key);
}
Ebook(const Ebook &ref) :Book(ref) //복사생성자
{
DRMKey = new char[strlen(ref.DRMKey) + 1];
strcpy(DRMKey, ref.DRMKey);
}
Ebook &operator=(const Ebook &ref) //대입연산자
{
cout << "Ebook &operator=()" << endl;
Book::operator=(ref);
delete[]DRMKey;
DRMKey = new char[strlen(ref.DRMKey) + 1];
strcpy(DRMKey, ref.DRMKey);
return *this;
}
void ShowEBookInfo()
{
ShowBookInfo();
cout << "인증키: " << DRMKey << endl;
}
~Ebook()
{
delete[]DRMKey;
}
};
int main(void)
{
Ebook ebook1("좋은 C++ ebook", "555-12345-890-1", 10000, "fdx9w0i8kiw");
Ebook ebook2 = ebook1; //복사 생성자의 호출
ebook2.ShowEBookInfo();
cout << endl;
Ebook ebook3("gudetama", "gudetama", 0, "gudetama");
ebook3 = ebook2; //대입 연산자의 호출
ebook3.ShowEBookInfo();
return 0;
}
개발 환경:Visual Studio 2017
지적, 조언, 질문 환영입니다! 댓글 남겨주세요~
[참고] 열혈 C++ 프로그래밍 윤성우 저
'C++ > 열혈 C++ 프로그래밍(윤성우 저)' 카테고리의 다른 글
OOP 단계별 프로젝트 8 (0) | 2017.06.12 |
---|---|
열혈 C++ 프로그래밍 11-2 문제 (0) | 2017.06.12 |
열혈 C++ 프로그래밍 10-3 문제 (0) | 2017.06.08 |
열혈 C++ 프로그래밍 10-2 문제 (0) | 2017.06.08 |
열혈 C++ 프로그래밍 10-1 문제 (0) | 2017.06.08 |