[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++ 프로그래밍 입문 황준하 저
'C++ > 기초를 탄탄히 세워주는 C++ 프로그래밍 입문(황준하 저)' 카테고리의 다른 글
기초를 탄탄히 세워주는 C++ 프로그래밍 입문 14장 연습문제 (0) | 2017.07.16 |
---|---|
기초를 탄탄히 세워주는 C++ 프로그래밍 입문 13장 연습문제 (0) | 2017.07.14 |
기초를 탄탄히 세워주는 C++ 프로그래밍 입문 12장 연습문제 (3) | 2017.07.12 |
기초를 탄탄히 세워주는 C++ 프로그래밍 입문 11장 연습문제 (0) | 2017.07.10 |
기초를 탄탄히 세워주는 C++ 프로그래밍 입문 10장 연습문제 (0) | 2017.07.07 |