Minwoo Dev.

[C++] 윤성우의 열혈 C++ 11-1 깊은 복사를 하는 대입 연산자의 정의 문제풀이 본문

C++

[C++] 윤성우의 열혈 C++ 11-1 깊은 복사를 하는 대입 연산자의 정의 문제풀이

itisminu 2024. 5. 16. 15:37
728x90
반응형
SMALL

문제 1

Chapter 07에서는 예제 HASComposite.cpp를 통해서 다음의 두 클래스를 정의하였다.(완전한 클래스의 정의는 예제를 참고하자.)

 

class Gun{

    ...

}

class Police {
    private:
    int handcuffs;
    Gun * pistol;
    public:
     .... 
}

 

이에 Police 클래스를 대상으로 깊은 복사가 이뤄지도록 대입 연산자와 복사 생성자를 동시에 정의하고 이의 확인을 위한 main 함수도 적절히 정의해보자.

 

 

정답

#include <iostream>
using namespace std;

class Gun
{
private:
    int bullet;

public:
    Gun(int bnum) : bullet(bnum) {}
    void Shot()
    {
        cout << "BBANG!" << endl;
        bullet--;
    }
    int GetBullet()
    {
        return bullet;
    }
};

class Police
{
private:
    int handcuffs;
    Gun *pistol;

public:
    Police(int bnum, int bcuff) : handcuffs(bcuff)
    {
        if (bnum < 0)
            pistol = new Gun(bnum);
        else
            pistol = NULL;
    }
    Police(const Police &ref) : handcuffs(ref.handcuffs)
    {
        if (ref.pistol != NULL)
            pistol = new Gun(*(ref.pistol));
        else
            pistol = NULL;
    }
    void PutHandcuff()
    {
        cout << "SNAP!" << endl;
        handcuffs--;
    }

    void Shot()
    {
        if (pistol == NULL)
            cout << "Hut BBANG!" << endl;
        else
            pistol->Shot();
    }
    ~Police()
    {
        if (pistol != NULL)
            delete pistol;
    }
    Police &operator=(const Police &ref)
    {
        if (pistol != NULL)
            delete pistol;
        if (ref.pistol != NULL)
            pistol = new Gun(*(ref.pistol));
        else
            pistol = NULL;
        handcuffs = ref.handcuffs;
        return *this;
    }
};

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;

public:
    Book(char *title, char *isbn, int value) : price(value)
    {
        this->title = new char[strlen(title) + 1];
        this->isbn = new char[strlen(isbn) + 1];
        strcpy(this->title, title);
        strcpy(this->isbn, isbn);
    }
    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 *title, char *isbn, int value, char *key) : Book(title, isbn, value)
    {
        DRMKey = new char[strlen(key) + 1];
        strcpy(DRMKey, key);
    }

    void ShoiwEBookInfo()
    {
        ShowBookInfo();
        cout << "인증키 : " << DRMKey << endl;
    }
    ~EBook()
    {
        delete[] DRMKey;
    }
};

 

 

이 때 정의한 두 클래스를 대상으로 Book 클래스도, EBook 클래스도 깊은 복사가 진행이 되도록 복사 생성자와 대입 연산자를 정의하고, 이의 확인을 위한 main 함수도 적절히 정의해보자.

 

 

정답

#include <iostream>
using namespace std;

class Book
{
private:
    char *title;
    char *isbn;
    int price;

public:
    Book(char *title, char *isbn, int value) : price(value)
    {
        this->title = new char[strlen(title) + 1];
        this->isbn = new char[strlen(isbn) + 1];
        strcpy(this->title, title);
        strcpy(this->isbn, isbn);
    }
    Book(const Book &ref) : price(ref.price)
    {
        this->title = new char[strlen(ref.title) + 1];
        this->isbn = new char[strlen(ref.isbn) + 1];
        strcpy(this->title, ref.title);
        strcpy(this->isbn, ref.isbn);
    }
    Book &operator=(const Book &ref)
    {
        delete[] title;
        delete[] isbn;
        this->title = new char[strlen(ref.title) + 1];
        this->isbn = new char[strlen(ref.isbn) + 1];
        strcpy(this->title, ref.title);
        strcpy(this->isbn, ref.isbn);
        this->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 *title, char *isbn, int value, char *key) : Book(title, isbn, value)
    {
        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)
    {
        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++", "aa", 18000, "a1");
    EBook ebook2 = ebook1;
    ebook2.ShowEBookInfo(); // 복사 생성자 호출
    cout << endl;
    EBook ebookcpy("dumy", "dumy", 0, "dumy");
    ebookcpy = ebook1; // 대입 연산자 호출
    ebookcpy.ShowEBookInfo();
}

 

 

실행 결과

728x90
반응형
LIST