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

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

꾸준함. 2017. 7. 18. 00:14

[15.1]

/*

다음과 같은 구조체 Point가 있다.

auto_ptr를 사용하여 Point 구조체 변수를 동적으로 생성하는 main 함수를 작성해 본다.

struct Point

{

        int x, y;

};

auto_ptr의 실제 타입으로 구조체가 올 경우를 대비하여 -> 연산자를 준비해 두고 잇다고 하였다.

여기서는 -> 연산자를 사용해보도록 한다

*/

#include <iostream>

#include <memory>

using namespace std;

 

struct Point

{

        int x, y;

};

 

int main(void)

{

        auto_ptr<Point> p(new Point);

        p->x = 5;

        p->y = 5;

        cout << "좌표: ";

        cout << "(" << p->x << ", " << p->y << ")" << endl;

        return 0;

}

 

 

[15.2]

/*

배열의 동적 생성 및 해제를 자동화하기 위한 클래스 AutoAryPtr를 만들어 본다

다음 main 함수와 같이 수행될 수 있어야 한다

*/

#include <iostream>

using namespace std;

 

template <typename T>

class AutoAryPtr

{

private:

        T *ptr;

public:

        AutoAryPtr(T *p) :ptr(p)

        {

        }

        T &operator[](T i)

        {

               return ptr[i];

        }

        ~AutoAryPtr()

        {

               delete ptr;

        }

};

 

int main(void)

{

        int i;

        AutoAryPtr<int> p(new int[10]);

        for (i = 0; i < 10; i++)

               p[i] = i*i; //[] 연산자 오버로딩

        for (i = 0; i < 10; i++)

               cout << i << " : " << p[i] << endl;

        return 0;

}

 

[15.3]

/*

예제 15.4에서 대입 연산자 오버로딩을 사용하지 않고 변환함수만을 사용하여 2, 3, 4의 대입이 모두 가능하도록

수정해 본다

*/

#include <iostream>

using namespace std;

 

class base

{

public:

        int x;

 

        base(int a = 0) //4 해결

        {

               cout << "int->base 형변환" << endl;

               x = a; //base 객체는 int형 변수 가능

        }

        void show(void)

        {

               cout << "base: " << x << endl;

        }

};

 

class derived :public base

{

public:

        int y;

        derived(int a = 0, int b = 0) :base(a)

        {

               y = b;

        }

        derived(base &b) :base(b.x) //2 해결

        {

               cout << "derived 객체->base 객체 형변환" << endl;

               y = b.x;

        }

        void show(void)

        {

               base::show();

               cout << "derived: " << y << endl;

        }

        /*

        void operator=(const base &b) //derived 객체=base 객체 가능

        {

               x = b.x;

               y = b.x;

        }

        */

};

 

class another

{

public:

        double z;

 

        another(double c = 0)

        {

               z = c;

        }

        another(base &b)

        {

               cout << "another 객체->base 객체 형변환" << endl;

               z = b.x; //3 해결

        }

        void show(void)

        {

               cout << "another: " << z << endl;

        }

        /*

        void operator=(const base &b) //another 객체=base 객체 가능

        {

               z = b.x;

        }

        */

};

 

int main(void)

{

        base b;

        derived d;

        another a;

        int i = 1;

        b = d;

        d = b;

        a = b;

        b = i;

 

        return 0;

}

[15.4]

/*

CPoint 클래스와 CCircle 클래스를 만들고 하나의 클래스 객체가 다른 클래스 객체로 대입될 수 있도록 한다.

CPoint 객체가 CCircle 객체로 변환될 때는 x, y는 각각의 x, y로 대입되고(x+y)가 반지름으로 대입된다.

거꾸로 CCircle 객체가 CPoint 객체로 변환될 때는 (x+y) x, 면적이 y로 대입되도록 한다.

*/

#include <iostream>

using namespace std;

 

#define PI 3.14

 

class CPoint

{

public:

        int x, y;

public:

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

        {

        }

        void show(void)

        {

               cout << "좌표: ";

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

        }

        CPoint &CPoint::operator=(class CCircle &Co);

};

 

class CCircle

{

public:

        int x;

        int y;

        int r;

        double area;

public:

        CCircle(int a = 0, int b = 0, int c = 1) :x(a), y(b), r(c)

        {

               area = r*r*PI;

        }

        void show(void)

        {

               cout << "중심: ";

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

               cout << "반지름: ";

               cout << r;

               cout << " 넓이: ";

               cout << area << endl;

        }

        void operator=(const CPoint &Po)

        {

               x = Po.x;

               y = Po.y;

               r = Po.x + Po.y;

               area = r*r*PI;

        }

        int GetX()

        {

               return x;

        }

        int GetY()

        {

               return y;

        }

        int GetArea()

        {

               return area;

        }

};

 

CPoint &CPoint::operator=(class CCircle &Co)

{

        x = Co.GetX() + Co.GetY();

        y = Co.GetArea();

        return (*this);

}

 

int main(void)

{

        CPoint Po(1, 1);

        CPoint copy;

        CCircle Co(2, 2, 2);

        CCircle copy2;

        cout << "CPoint" << endl;

        Po.show();

        cout << "CCircle" << endl;

        Co.show();

        cout << "CPoint 객체에 CCircle 객체를 복사" << endl;

        copy = Co;

        copy.show();

        cout << "CCircle 객체에 CPoint 객체를 복사" << endl;

        copy2 = Po;

        copy2.show();

        return 0;

}

[15.5]

/*

다음 프로그램에서 RunFunc의 주석과 같이 수행될 수 있도록 RunFunc 함수를 완성해 본다

*/

#include <iostream>

using namespace std;

 

class Base

{

public:

        int b;

        virtual void func()

        {

               cout << "Base" << endl;

        }

};

 

class Derived :public Base

{

public:

        int d;

        void func()

        {

               cout << "Derived" << endl;

        }

        void func2()

        {

               cout << "Dervied::func2" << endl;

        }

};

 

void RunFunc(Base *b)

{

        //Base가 가리키는 객체가 Base 객체라면 func를 수행하고

        if (typeid(*b) == typeid(Base))

               b->func();

        //Derived 객체를 가리키고 있다면 func2를 수행해라

        if (typeid(*b) == typeid(Derived))

        {

               Derived *d = static_cast<Derived*>(b);;

               d->func2();

        }

}

 

int main(void)

{

        Base *b = new Derived();

        RunFunc(b);

 

        return 0;

}

[15.6]

/*

다음 프로그램의 출력 결과는 무엇인가?

15라인을 주석 처리하고 대신 14라인을 수행시키면 어떻게 되는가?

8라인에서는 Print 멤버 함수를 왜 const 함수로 만들었는가?

13라인의 CPoint 객체를 const 객체로 만든다는 전제하에 이 모든 질문에 대해 답하도록 한다

*/

#include <iostream>

using namespace std;

 

class CPoint

{

private:

        int x, y;

public:

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

        {

        }

        void SetXY(int a, int b)

        {

               x = a;

               y = b;

        }

        void Print() const

        {

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

        }

};

 

int main(void)

{

        const CPoint ThePoint(100, 100);

        //ThePoint.SetXY(200, 200); //const이기 때문에 형변환 없이 X Y 값 변환 X

        const_cast<CPoint*>(&ThePoint)->SetXY(200, 200);

 

        ThePoint.Print(); //const 객체를 선언했기 때문에 Print 함수도 const

        return 0;

}

[15.7]

/*

다음 코드에서 main 함수의 b[i] Base 객체 또는 Derived 객체를 가리키는 포인터이다.

사용자의 입력에 따라 Base 객체 또는 Derived 객체를 동적으로 생성하여 b[i] 포인터가 가리키도록 한다

그리고 제대로 생성되었는지 typeid 연산자를 통해 확인해 본다

*/

#include <iostream>

using namespace std;

 

class Base

{

public:

        int b;

        virtual void func()

        {

               cout << "Base" << endl;

        }

};

 

class Derived :public Base

{

public:

        int d;

        void func()

        {

               cout << "Derived" << endl;

        }

        void func2()

        {

               cout << "func2" << endl;

        }

};

 

int main(void)

{

        int i, input;

        Base *b[5];

        for (i = 0; i < 5; i++)

        {

               cout << i << "번째 객체(Base:1, Derived:2): ";

               cin >> input;

               if (input == 1)

               {

                       b[i] = new Base();

               }

               else if (input == 2)

               {

                       b[i] = new Derived();

               }

               else

               {

                       i--;

                       continue;

               }

        }

 

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

        {

               cout << "b[" << i << "]" << " : " << typeid(*b[i]).name() << endl;

        }

        return 0;

}


개발 환경:Visual Studio 2017


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


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

반응형