Minwoo Dev.

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

C++

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

itisminu 2024. 7. 21. 11:08
728x90
반응형
SMALL

문제 1

Chapter 07에서는 예제 HASComposite.cpp를 통해서 다음의 두 클래스를 정의하였다.

 

HASComposite.cpp

class Gun{
private:
    int bullet;
public:
    Gun(int bnum):bullet(bnum){}
    void Shot(){
        cout << "BBNAG!" << endl;
        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;
    }
    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 클래스를 대상으로 깊은 복사가 이뤄지도록 대입 연산자와 복사 생성자를 동시에 정의하고 이의 확인을 위한 main 함수도 적절히 정의해보자.

 

정답

#include<iostream>
using namespace std;

class Gun{
private:
    int bullet;
public:
    Gun(int bnum):bullet(bnum){}
    void Shot(){
        cout << "BBNAG!" << endl;
        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;
    }
    Police& operator=(const Police& p){
        handcuffs = p.handcuffs;
        if(pistol!=NULL)
            delete pistol;

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

int main(void){
    Police man1(3, 2);
    Police man2=man1;
    man2.PutHandcuff();
    man2.Shot();

    Police man3(2, 3);
    man3 = man1;
    man3.PutHandcuff();
    man3.Shot();
    return 0;
}

 

 

실행 결과

 

 

 

문제 2

Chapter 07의 문제 07-2의 두 번째 문제에서는 다음의 두 클래스 정의를 요구하였다.

 

class Book{
private:
    char *title;
    char *isbn;
    int price;
public:
    Book(char* title, char* isbn, int price):price(price){
        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;
    }
};

class EBook : public Book{
private:
    char *DRMKey;
public:
    EBook(char*title, char* isbn, int price, char* DRMKey):Book(title, isbn,price){
        this->DRMKey = new char[strlen(DRMKey) + 1];
        strcpy(this->DRMKey, DRMKey);
    }
};

 

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

 

 

정답

#include<iostream>
#include<cstring>
using namespace std;

class Book{
private:
    char *title;
    char *isbn;
    int price;
public:
    Book(char* title, char* isbn, int price):price(price){
        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){
        title = new char[strlen(ref.title) + 1];
        isbn = new char[strlen(ref.isbn) + 1];
        strcpy(title, ref.title);
        strcpy(isbn, ref.isbn);
    }
    Book& operator=(const Book& book){
        if(this == &book) return *this; // 자기 자신을 대입하는 경우 처리

        delete[] title; // 기존 메모리 해제
        delete[] isbn;  // 기존 메모리 해제

        title = new char[strlen(book.title) + 1];
        isbn = new char[strlen(book.isbn) + 1];
        strcpy(title, book.title);
        strcpy(isbn, book.isbn);
        price = book.price;
        return *this;
    }
    void ShowBookInfo() const {
        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 price, char* DRMKey):Book(title, isbn, price){
        this->DRMKey = new char[strlen(DRMKey) + 1];
        strcpy(this->DRMKey, DRMKey);
    }
    EBook(const EBook& ref):Book(ref){
        DRMKey = new char[strlen(ref.DRMKey) + 1];
        strcpy(DRMKey, ref.DRMKey);
    }
    EBook& operator=(const EBook& eb){
        if(this == &eb) return *this; // 자기 자신을 대입하는 경우 처리

        Book::operator=(eb); // 기본 클래스 부분 복사

        delete[] DRMKey; // 기존 메모리 해제
        DRMKey = new char[strlen(eb.DRMKey) + 1];
        strcpy(DRMKey, eb.DRMKey);
        return *this;
    }
    void ShowBookInfo() const {
        Book::ShowBookInfo();
        cout << "DRM Key: " << DRMKey << endl;
    }
    ~EBook(){
        delete[] DRMKey;
    }
};

int main(void){
    Book book1("C++의 정석", "123-4455-2342-0", 20000);
    Book book2 = book1;
    book2.ShowBookInfo();
    Book book3("C++ 쉽게 배우기", "123-2222-1892-0" ,15000);
    book3 = book1;
    book3.ShowBookInfo();

    EBook ebook1("C++의 정석", "123-4455-2342-1", 18000,"sd5ds68fa");
    EBook ebook2 = ebook1;
    ebook2.ShowBookInfo();
    EBook ebook3("C++ 쉽게 배우기", "123-2222-1892-1", 13000,"fdas32");
    ebook3 = ebook1;
    ebook3.ShowBookInfo();
    return 0;
}

 

 

실행 결과

 

 

 

 

 

Note) 대입 연산자의 경우에, 자기 자신을 대입하는 경우에 대한 예외 처리를 해주어야 한다!!

 

728x90
반응형
LIST