C++/열혈 C++ 프로그래밍(윤성우 저)

열혈 C++ 프로그래밍 11-2 문제

꾸준함. 2017. 6. 12. 19:59

[1번 문제]

/*

예제 StablePointPtrArray.cpp 65, 66행을 다음과 같이 구성할 수 있도록 Point 클래스를 대상으로 연산자 오버로딩을 진행해보자

for(int i=0; i<arr.GetArrLen(); i++)

        cout<<arr[i];

물론, 실행결과에는 변함이 없도록 오버로딩 해야 한다.

*/

 

//StablePointPtrArray.cpp

/*

#include <iostream>

#include <cstdlib>

using namespace std;

 

class Point

{

private:

        int xpos, ypos;

public:

        Point(int x = 0, int y = 0) :xpos(x), ypos(y)

        {

        }

        friend ostream &operator<<(ostream &os, const Point &pos);

};

 

ostream &operator<<(ostream &os, const Point &pos)

{

        os << '[' << pos.xpos << ", " << pos.ypos << ']' << endl;

        return os;

}

 

typedef Point *POINT_PTR; //Point 포인터 형을 의미하는 POINT_PTR을 정의하였다. 저장의 대상, 또는 연산의 주 대상이 포인터인 경우, 이렇듯 별도의 자료형을 정의하는 것이 좋다

 

class BoundCheckPointPtrArray

{

private:

        POINT_PTR *arr;

        int arrlen;

 

        BoundCheckPointPtrArray(const BoundCheckPointPtrArray &arr)

        {

        }

        BoundCheckPointPtrArray &operator=(const BoundCheckPointPtrArray &arr)

        {

        }

public:

        BoundCheckPointPtrArray(int len) :arrlen(len)

        {

               arr = new POINT_PTR[len]; //저장의 대상이 Point 객체의 주소 값이기 때문에 POINT_PTR 배열을 생성

        }

        POINT_PTR &operator[](int idx)

        {

               if (idx < 0 || idx >= arrlen)

               {

                       cout << "Array index out of bound exception" << endl;

                       exit(1);

               }

               return arr[idx];

        }

        POINT_PTR operator[](int idx) const

        {

               if (idx < 0 || idx >= arrlen)

               {

                       cout << "Array index out of bound exception" << endl;

                       exit(1);

               }

               return arr[idx];

        }

        int GetArrLen() const

        {

               return arrlen;

        }

        ~BoundCheckPointPtrArray()

        {

               delete[]arr;

        }

};

 

int main(void)

{

        BoundCheckPointPtrArray arr(3);

        arr[0] = new Point(3, 4);

        arr[1] = new Point(5, 6);

        arr[2] = new Point(7, 8);

 

        for (int i = 0; i < arr.GetArrLen(); i++)

               cout << *(arr[i]);

        delete arr[0];

        delete arr[1];

        delete arr[2];

        return 0;

}

*/

#include <iostream>

#include <cstdlib>

using namespace std;

 

class Point

{

private:

        int xpos, ypos;

public:

        Point(int x = 0, int y = 0) :xpos(x), ypos(y)

        {

        }

        friend ostream &operator<<(ostream &os, const Point *pos); //추가된 대입연산자

        friend ostream &operator<<(ostream &os, const Point &pos);

};

 

ostream &operator<<(ostream &os, const Point *pos)//추가된 대입연산자

{

        os << '[' << pos->xpos << ", " << pos->ypos << ']' << endl;

        return os;

}

 

ostream &operator<<(ostream &os, const Point &pos)

{

        os << '[' << pos.xpos << ", " << pos.ypos << ']' << endl;

        return os;

}

 

typedef Point *POINT_PTR; //Point 포인터 형을 의미하는 POINT_PTR을 정의하였다. 저장의 대상, 또는 연산의 주 대상이 포인터인 경우, 이렇듯 별도의 자료형을 정의하는 것이 좋다

 

class BoundCheckPointPtrArray

{

private:

        POINT_PTR *arr;

        int arrlen;

 

        BoundCheckPointPtrArray(const BoundCheckPointPtrArray &arr)

        {

        }

        BoundCheckPointPtrArray &operator=(const BoundCheckPointPtrArray &arr)

        {

        }

public:

        BoundCheckPointPtrArray(int len) :arrlen(len)

        {

               arr = new POINT_PTR[len]; //저장의 대상이 Point 객체의 주소 값이기 때문에 POINT_PTR 배열을 생성

        }

        POINT_PTR &operator[](int idx)

        {

               if (idx < 0 || idx >= arrlen)

               {

                       cout << "Array index out of bound exception" << endl;

                       exit(1);

               }

               return arr[idx];

        }

        POINT_PTR operator[](int idx) const

        {

               if (idx < 0 || idx >= arrlen)

               {

                       cout << "Array index out of bound exception" << endl;

                       exit(1);

               }

               return arr[idx];

        }

        int GetArrLen() const

        {

               return arrlen;

        }

        ~BoundCheckPointPtrArray()

        {

               delete[]arr;

        }

};

 

int main(void)

{

        BoundCheckPointPtrArray arr(3);

        arr[0] = new Point(3, 4);

        arr[1] = new Point(5, 6);

        arr[2] = new Point(7, 8);

 

        for (int i = 0; i < arr.GetArrLen(); i++)

               cout << arr[i];

        delete arr[0];

        delete arr[1];

        delete arr[2];

        return 0;

}

 


[2번 문제]

/*

이번에는 재미삼아서 2차원 배열접근에 대한 연산자 오버로딩을 진행하고자 한다.

실제로 이렇게까지 연산자를 직접 오버로딩 하는 경우는 거의 없다.

다만, 필자는 호기심을 유발 및 충족시킨다는 측면에서 이 문제를 제시하는 것이다.

그러니 여러분도 이 문제에 단순한 호기심과 즐거움을 느꼈으면 좋곘다. 그럼 문제를 제시하겠다.

다음의 이름으로 클래스를 정의하자.

class BoundCheck2DIntArray{...}

이 클래스는 BoundCheckIntArray 클래스의 2차원 배열 버전이다.

따라서 다음과 같이 객체를 생성하면,

BoundCheck2DIntArray arr2d(3, 4);

세로와 가로의 길이가 각각 3 4, int 2차원 배열처럼 동작하는 arr2d 객체가 생성되어,

다음의 형태로 데이터를 저장 및 참조할 수 있어야 한다.

for (int n = 0; n < 3; n++)

        for (int m = 0; m < 4; m++)

               arr2d[n][m] = n + m;

 

for (int n = 0; n < 3; n++)

{

        for (int m = 0; m < 4; m++)

               cout << arr2d[n][m] << ' ';

        cout << endl;

}

참고로 두개의 []연산자를 동시에 오버로딩 하는 것은 허용되지 않기 때문에, 위의 다음 문장은,

arr2d[n][m]

두번의 []연산자 호출을 동반하게끔 구현해야 한다.

, 첫번째 []연산에 의해서 위의 문장은 다음과 같이 해석되어야 하며,

(arr2d.operator[](n))[m];

그리고 arr2d.operator[](n)연산의 반환 값을 이용해서 두 번째[] 연산은 다음과 같이 해석되어야한다.

((반환 값).operator[])(m);

*/

#include <iostream>

#include <cstdlib>

using namespace std;

 

class BoundCheckIntArray //1차원 배열

{

private:

        int *arr;

        int arrlen;

        BoundCheckIntArray(const BoundCheckIntArray &arr)

        {

        }

        BoundCheckIntArray &operator=(const BoundCheckIntArray &arr)

        {

        }

public:

        BoundCheckIntArray(int len) :arrlen(len)

        {

               arr = new int[len];

        }

        int &operator[](int idx)

        {

               if (idx < 0 || idx >= arrlen)

               {

                       cout << "Array index out of bound exception" << endl;

                       exit(1);

               }

               return arr[idx];

        }

        int operator[](int idx) const

        {

               if (idx < 0 || idx >= arrlen)

               {

                       cout << "Array index out of bound exception" << endl;

                       exit(1);

               }

               return arr[idx];

        }

        int GetArrLen() const

        {

               return arrlen;

        }

        ~BoundCheckIntArray()

        {

               delete[]arr;

        }

};

 

typedef BoundCheckIntArray *BoundCheckIntArrayPtr;

 

class BoundCheck2DIntArray

{

private:

        BoundCheckIntArray **arr;

        //int column; //처음에는 가로 세로 따로 선언하여 C언어에서처럼 이차원배열을 동적할당하려 하였다

        //int row;

        int arrlen;

        BoundCheck2DIntArray(const BoundCheck2DIntArray &arr)

        {

        }

        BoundCheck2DIntArray &operator=(const BoundCheck2DIntArray &arr)

        {

        }

public:

        BoundCheck2DIntArray(int col, int row) :arrlen(col)

        {

               arr = new BoundCheckIntArrayPtr[col];

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

                       arr[i] = new BoundCheckIntArray(row);

        }

        BoundCheckIntArray &operator[](int idx)

        {

               if (idx < 0 || idx >= arrlen)

               {

                       cout << "Array index out of bound exception" << endl;

                       exit(1);

               }

               return *(arr[idx]);

        }

        ~BoundCheck2DIntArray()

        {

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

                       delete arr[i];

               delete[]arr;

        }

};

 

int main(void)

{

        BoundCheck2DIntArray arr2d(3, 4);

 

        for (int n = 0; n < 3; n++)

               for (int m = 0; m < 4; m++)

                       arr2d[n][m] = n + m;

        for (int n = 0; n < 3; n++)

        {

               for (int m = 0; m < 4; m++)

                       cout << arr2d[n][m] << ' ';

               cout << endl;

        }

        return 0;

}


개발 환경:Visual Studio 2017


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


[참고] 열혈 C++ 프로그래밍 윤성우 저

반응형