C++/기초를 탄탄히 세워주는 C++ 프로그래밍 입문(황준하 저)

기초를 탄탄히 세워주는 C++ 프로그래밍 입문 6장 연습문제

꾸준함. 2017. 7. 2. 10:00

[6.1]

/*

다음 프로그램의 문제점이 무엇인지 메모리 구조와 관련하여 설명해 본다

*/

#include <iostream>

using namespace std;

 

class CArray

{

private:

        int *ary;

        int count;

public:

        CArray(int c = 1)

        {

               count = c;

               ary = new int[count];

               for (int i = 0; i < count; i++)

                       ary[i] = i;

        }

        //이 문장을 추가하면 오류 해결(main문에서 delete Ary1을 해줘야한다)

        /*

        CArray(const CArray &copy)

        {

               count = copy.count;

               ary = new int[count];

               for (int i = 0; i < count; i++)

                       ary[i] = i;

        }

        */

        ~CArray()

        {

               delete[]ary;

        }

        void Print()

        {

               for (int i = 0; i < count; i++)

                       cout << ary[i] << " ";

               cout << endl;

        }

};

 

int main(void)

{

        CArray *Ary1 = new CArray(3);

        CArray Ary2(*Ary1);

        CArray Ary3;

        Ary3 = *Ary1;

 

        Ary1->Print();

        Ary2.Print();

        Ary3.Print();

 

        delete Ary1; //복사생성자문 입력시 이 문장을 주석 처리

        //Ary1이 소멸된 후 Ary2 Ary3가 소멸할 메모리가 존재하지 않기 떄문에 에러가 발생한다

        return 0;

}

[6.2]

/*

다음 프로그램은 지역 객체들에 대한 메모리 구조를 설명해 보고 출력 결과가 무엇인지,

문제가 있다면 왜 문제가 발생하는지에 대해 설명해본다.

예제 6.5 CString 클래스를 그대로 사용한다고 가정한다

*/

#include <iostream>

#include <cstring>

using namespace std;

 

class CString

{

private:

        int len;

        char *str;

public:

        CString(char *s = "Unknown")

        {

               len = strlen(s);

               str = new char[len + 1];

               strcpy(str, s);

        }

        //이 문장(복사생성자) 삽입시 정상적으로 실행

        /*

        CString(const CString &copy)

        {

               len = copy.len;

               str = new char[len + 1];

               strcpy(str, copy.str);

        }

        */

        ~CString()

        {

               delete[]str;

        }

        void Print()

        {

               cout << str << endl;

        }

};

 

void ShowString(CString str, int count) //재귀 호출

{

        if (count < 0)

               return;

 

        cout << "count: " << count << endl;

        str.Print();

        ShowString(str, count - 1);

}

 

int main(void)

{

        CString str1 = "C++ Programming";

        ShowString(str1, 3);

        //재귀호출을 마치고 소멸될 때 count 0 str1이 먼저 소멸된다.

        //이후에 count 1, count 2, count 3 str1도 소멸자에 의해 delete가 되기를 기대하지만

        //이미 str1은 소멸되었으므로 소멸될 대상이 없기 때문에 에러가 난다

        return 0;

}

[6.3]

/*

다음 main 함수에서 CPoint 객체 생성을 위해 필요한 모든 생성자를 포함하도록 CPoint

클래스를 작성해본다. 필요한 모든 생성자는 명시적으로 구현해야만 한다

*/

#include <iostream>

using namespace std;

 

class CPoint

{

private:

        int x;

        int y;

public:

        CPoint() :x(0), y(0)

        {

        }

        CPoint(int a) :x(a), y(a)

        {

        }

        CPoint(int a, int b) :x(a), y(b)

        {

        }

        CPoint(int a, const CPoint &P)

        {

               x = a*P.x;

               y = a*P.y;

        }

        CPoint(const CPoint &P1, const CPoint &P2)

        {

               x = P1.x + P2.x;

               y = P1.y + P2.y;

        }

        CPoint(const CPoint &copy) //복사 생성자

        {

               x = copy.x;

               y = copy.y;

        }

        void Print()

        {

               cout << "(" << x << ", " << y << ")" << endl;

        }

};

 

int main(void)

{

        CPoint P1;

        CPoint P2(1);

        CPoint P3(2, 3);

        CPoint P4 = P3;

        CPoint P5(2, P3);

        CPoint P6(P4, P5);

 

        P1.Print();

        P2.Print();

        P3.Print();

        P4.Print();

        P5.Print();

        P6.Print();

 

        return 0;

}

[6.4]

/*

다음 프로그램의 문제점은 무엇인지 설명한다

*/

#include <iostream>

using namespace std;

 

class CPoint

{

private:

        int x, y;

public:

        //복사생성자가 따로 명시되면 디폴트 생성자도 존재하지 않게 된다

        //따라서 생성자를 별도로 추가시켜줘야한다

        /*

        CPoint() :x(0), y(0)

        {

        }

        */

        CPoint(const CPoint &Po) //복사 생성자

        {

               x = Po.x;

               y = Po.y;

        }

        void Print()

        {

               cout << "(" << x << ", " << y << ")" << endl;

        }

};

 

int main(void)

{

        CPoint P1; //디폴트 생성자가 존재하지 않기 때문에 에러

        CPoint P2(P1); //복사 생성

 

        P1.Print();

        P2.Print();

 

        return 0;

}

 

[6.5]

/*

CArray 클래스는 임의 개수의 int형 원소를 저장할 수 있는 클래스이다.

이를 위해 배열을 가리키는 포인터 변수(int *ary)와 원소의 개수를 의미하는 int형 변수(int count)를 멤버 변수로 가지고 있다.

다음 main 함수와 실행 화면을 참고하여 CArray 클래스를 작성해 본다.

*/

#include <iostream>

#include <cstring>

using namespace std;

 

class CArray

{

private:

        int *arr;

        int len;

public:

        CArray(int num) :len(num)

        {

               arr = new int[len];

               for (int i = 0; i < len; i++)

                       arr[i] = i;

        }

        CArray(const CArray &copy) :len(copy.len) //복사생성자

        {

               arr = new int[len];

               for (int i = 0; i < len; i++)

                       arr[i] = i;

        }

        CArray &Set(int num, int a) //클래스 참조 반환

        {

               arr[num] = a;

               return *this;

        }

        void Print()

        {

               for (int i = 0; i < len; i++)

                       cout << arr[i] << " ";

               cout << endl;

        }

};

 

int main(void)

{

        CArray Ary1(5);

        CArray Ary2(7);

        CArray Ary3(Ary1);

 

        Ary2.Set(0, 11).Set(1, 12).Set(2, 13);

 

        Ary1.Print();

        Ary2.Print();

        Ary3.Print();

 

        return 0;

}

 

[6.6]

/*

main 함수가 실행결과와 같이 수행될 수 있도록 CArray 클래스와 Sum 함수를 작성해 본다

*/

#include <iostream>

using namespace std;

 

class CArray

{

private:

        int *arr;

        int len;

public:

        CArray(int num) :len(num)

        {

               arr = new int[len];

               for (int i = 0; i < len; i++)

                       arr[i] = i;

        }

        CArray(const CArray &copy) :len(copy.len)

        {

               arr = new int[len];

               for (int i = 0; i < len; i++)

                       arr[i] = copy.arr[i];

        }

        ~CArray()

        {

               delete[]arr;

        }

        CArray &Set(int num, int a)

        {

               arr[num] = a;

               return *this;

        }

        void Print()

        {

               for (int i = 0; i < len; i++)

                       cout << arr[i] << " ";

               cout << endl;

        }

        int length() //길이

        {

               return len;

        }

        int index(int len) //값 반환

        {

               return arr[len];

        }

};

 

CArray Sum(CArray A1, CArray A2)

{

        //같은 원소끼리 더한 결과로 만든 CArray 객체를 반환한다

        int minLen = (A1.length() < A2.length()) ? A1.length() : A2.length();

        int maxLen = (A1.length() < A2.length()) ? A2.length() : A1.length();

        CArray A3(maxLen); //전부 출력해야하기 때문에

        for (int i = 0; i < minLen; i++)

        {

               A3.Set(i, A1.index(i) + A2.index(i));

        }

        for (int i = minLen; i < maxLen; i++)

        {

               if (A1.length() > A2.length()) //A1이 더 긴 경우

                       A3.Set(i, A1.index(i));

               else //A2가 더 긴 경우

                       A3.Set(i, A2.index(i));

        }

        return A3;

}

 

int main(void)

{

        CArray Ary1(5);

        CArray Ary2(7);

        Ary2.Set(0, 11).Set(1, 12).Set(2, 13);

 

        CArray Ary3 = Sum(Ary1, Ary2);

 

        Ary1.Print();

        Ary2.Print();

        Ary3.Print();

 

        return 0;

}

[6.7]

/*

main 함수와 실행 결과를 참고하여 2개의 CPoint 객체를 매개 변수로 전달 받아,

두점에 대한 합과 차에 대한 새로운 CPoint 객체를 만들어 반환하는 Sum, Sub 함수를 작성해본다.

객체 반환시에는 임시 객체를 사용하도록 한다

*/

#include <iostream>

using namespace std;

 

class CPoint

{

private:

        int x;

        int y;

public:

        CPoint(int a=0, int b=0) :x(a), y(b)

        {

        }

        CPoint(const CPoint &Po) //복사생성자

        {

               x = Po.x;

               y = Po.y;

        }

        int GetX()

        {

               return x;

        }

        int GetY()

        {

               return y;

        }

        void Print()

        {

               cout << "(" << x << ", " << y << ")" << endl;

        }

};

 

CPoint Sum(CPoint P1, CPoint P2)

{

        CPoint P3(P1.GetX() + P2.GetY(), P1.GetY() + P2.GetY());

        return P3;

 

}

 

CPoint Sub(CPoint P1, CPoint P2)

{

        CPoint P3(P1.GetX() - P2.GetX(), P1.GetY() - P2.GetY());

        return P3;

 

}

 

int main(void)

{

        CPoint P1(1, 2);

        CPoint P2(3, 4);

        CPoint P3 = Sum(P1, P2);

        CPoint P4 = Sub(P1, P2);

 

        P1.Print();

        P2.Print();

        P3.Print();

        P4.Print();

        return 0;

}



개발 환경:Visual Studio 2017


지적, 조언, 질문 환영입니다! 댓글 남겨주세요~


[참고] 기초를 탄탄히 세워주는 C++ 프로그래밍 입문 황준하 저

반응형