[9.1]
/*
그림 9.1과 같은 클래스 구성에 있어서 클래스 객체들 간의 복사 생성이 수행되는지
테스트해보도록 한다. 다음과 같은 코드가 수행 가능한지 생각해보면 된다
*/
#include <iostream>
using namespace std;
#define PI 3.14
class CPoint //임의로 추가한 CPoint 객체
{
private:
int x;
int y;
public:
CPoint(int a = 0, int b = 0) :x(a), y(b)
{
}
CPoint &operator=(const CPoint &Po)
{
cout << "CPoint 대입 연산자" << endl;
x = Po.x;
y = Po.y;
return (*this);
}
};
class CCircle
{
protected:
int x, y;
double Radius;
public:
CCircle(int a, int b, double r) :x(a), y(b), Radius(r)
{
}
double GetArea()
{
return (PI*Radius*Radius);
}
CCircle &operator=(const CCircle &Cir)
{
cout << "CCircle 대입 연산자" << endl;
x = Cir.x;
y = Cir.y;
Radius = Cir.Radius;
}
};
class CSphere:public CCircle
{
private:
int z;
public:
CSphere(int a, int b, int c, double r) :CCircle(a, b, r), z(c)
{
}
CSphere &operator=(const CSphere &Sph)
{
cout << "CSphere 대입 연산자" << endl;
z = Sph.z;
CCircle::operator=(Sph);
}
double GetArea()
{
return (4 * PI*Radius*Radius);
}
double GetVolume()
{
return ((4.0 / 3.0)*PI*Radius*Radius*Radius);
}
};
int main(void)
{
CPoint Po(1, 1);
CCircle Cir(2, 2, 2);
CSphere Sph(3, 3, 3, 3);
//CPoint Po2 = Cir; //무관한 클래스 객체 간 복사 생성(x)
CCircle Cir2 = Sph; //derived로부터 base 객체의 복사 생성(O)
//CSphere Sph2 = Cir; //base로부터 derived 객체의 복사 생성(x)
return 0;
}
[9.2]
/*
연습문제 9.1에서 7라인은 수행되지 않는다.
서로 무관한 클래스 객체 사이의 복사 생성 또는 대입은 기본적으로 허용되지 않기 때문이다.
그러나 이것이 가능하도록 만들 수는 있다.
CCircle 객체로부터 CPoint 객체를 복사 생성할 수 있도록 만들고 또한 CCircle 객체를 CPoint 객체로 대입할 수 있도록 만들어본다.
대입 연산자 오버로딩과 복사 생성자만 잘 이용하면 쉽게 해결할 수 있을 것이다.
대입 또는 복사 생성의 의미는 각자 알아서 부여하도록 한다.
*/
#include <iostream>
using namespace std;
#define PI 3.14
class CPoint; //미리 명시
class CCircle
{
protected:
int x, y;
double Radius;
public:
CCircle(int a, int b, double r) :x(a), y(b), Radius(r)
{
}
CCircle(const CCircle &cir)
{
x = cir.x;
y = cir.y;
}
double GetArea()
{
return (PI*Radius*Radius);
}
double GetRadius() const
{
return Radius;
}
int GetX() const
{
return x;
}
int GetY() const
{
return y;
}
CCircle &operator=(const CCircle &Cir)
{
cout << "CCircle 대입 연산자" << endl;
x = Cir.x;
y = Cir.y;
Radius = Cir.Radius;
}
void Print()
{
cout << "(" << x << ", " << y << ")" << endl;
cout << "반지름: " << Radius << endl;
}
};
class CPoint
{
private:
int x;
int y;
public:
CPoint(int a = 0, int b = 0) :x(a), y(b)
{
}
CPoint &operator=(const CCircle &cir)
{
x = cir.GetX();
y = cir.GetY();
return *this;
}
CPoint(CCircle &cir)
{
x = cir.GetX();
y = cir.GetY();
}
int GetX()
{
return x;
}
int GetY()
{
return y;
}
void Print()
{
cout << "(" << x << ", " << y << ")" << endl;;
}
};
int main(void)
{
CPoint Po(1, 1);
cout << "대입 전: ";
Po.Print();
CCircle Cir(3, 3, 3);
cout << "대입 후: ";
CPoint Po2 = Cir;
Po2.Print();
return 0;
}
[9.3]
/*
그림 9.4와 같은 클래스들이 존재한다.
다음 중 가능한 대입은 어느 것인가?
*/
#include <iostream>
using namespace std;
class A
{
public:
A()
{
cout << "A 생성자" << endl;
}
};
class B :public A
{
public:
B()
{
cout << "B 생성자" << endl;
}
};
class C :public B
{
public:
C()
{
cout << "C 생성자" << endl;
}
};
int main(void)
{
A objA;
C objC;
A *pA = &objC; //base 클래스가 derived 클래스를 대입하는 것은 가능
//C *pC = &objA; //반대로 derived 클래스가 base 클래스를 대입하는 것은 불가능
return 0;
}
[9.4]
/*
다음 프로그램의 출력 결과는 무엇인가?
*/
#include <iostream>
using namespace std;
class B
{
public:
B()
{
}
virtual void p()
{
cout << "B::p()" << endl;
}
void q()
{
cout << "B::q()" << endl;
}
};
class D :public B
{
public:
D()
{
}
virtual void p()
{
cout << "D::p()" << endl;
}
void q()
{
cout << "D::q()" << endl;
}
};
int main(void)
{
B b;
D d;
B *pb = new B;
B *pd = new D;
D *pd2 = new D;
b.p();
b.q();
d.p();
d.q();
pb->p();
pb->q();
pd->p(); //virtual이기 때문에 class D의 p()
pd->q();
pd2->p();
pd2->q();
return 0;
}
[9.5]
/*
다음 프로그램의 가상 함수 테이블을 비롯한 메모리 구조를 그려 본다.
base 클래스와 derived 클래스는 에제 9.7과 동일하다
*/
#include <iostream>
using namespace std;
class base
{
private:
int x;
public:
void func1()
{
cout << "base::func1" << endl;
}
virtual void func2()
{
cout << "base::func2" << endl;
}
virtual void func3()
{
cout << "base::func3" << endl;
}
};
class derived :public base
{
private:
int y;
public:
void func1()
{
cout << "derived::func1" << endl;
}
void func2()
{
cout << "derived::func2" << endl;
}
void func4()
{
cout << "derived::func4" << endl;
}
};
int main(void)
{
base Base[2];
derived Derived[2];
base *pBase;
int i, j;
for (i = 0; i < 2; i++)
{
for (j = 0; j < 2; j++)
{
if (i == 0)
pBase = &Base[j];
else
pBase = &Derived[j];
pBase->func1();
pBase->func2();
pBase->func3();
}
}
return 0;
}
[9.6]
/*
예제 9.9에서 CShape 클래스를 추상 클래스로 만들어 본다.
그리고 CShape, CCircle, CRect 클래 모두 객체의 면적을 출력하기 위한 Print 함수를 추가한다.
이 때 CShape 클래스의 경우 Print 함수를 순수 가상함수로 선언한다.
마지막으로 CShape 클래스에 출력 연산자 (<<) 오버로딩을 추가한다
*/
#include <iostream>
using namespace std;
class CShape
{
protected:
int x, y;
public:
CShape(int a, int b) :x(a), y(b)
{
}
void Move(int a, int b)
{
x += a;
y += b;
}
virtual void Print() = 0;//순수 가상 함수
friend ostream &operator<<(ostream &out, CShape &Sh);
};
ostream &operator<<(ostream &out, CShape &Sh) //<< 오버로딩
{
Sh.Print();
return out;
}
class CCircle :public CShape
{
private:
double Radius;
public:
CCircle(int a, int b, double r) :CShape(a, b), Radius(r)
{
}
virtual double GetArea()
{
return (3.14*Radius*Radius);
}
void Print()
{
cout << "원의 면적: " << GetArea() << endl;
}
};
class CRect :public CShape
{
private:
int Garo, Sero;
public:
CRect(int a, int b, int g, int s) :CShape(a, b), Garo(g), Sero(s)
{
}
double GetArea()
{
return (Garo*Sero);
}
void Print()
{
cout << "사각형의 면적: " << GetArea() << endl;
}
};
int main(void)
{
CCircle Cir(1, 1, 1);
CRect Rect(2, 2, 2, 2);
CShape *pSpe;
pSpe = &Cir;
cout << *pSpe;
pSpe = &Rect;
cout << *pSpe;
return 0;
}
[9.7]
/*
다음 프로그램의 출력 결과는 무엇인가?>
*/
#include <iostream>
using namespace std;
class Base
{
public:
Base()
{
cout << "Base::Base()" << endl;
}
Base(int n)
{
cout << "Base::Base(" << n << ")" << endl;
}
};
class Derived :public Base
{
private:
Base b;
public:
Derived()
{
cout << "D::D()" << endl;
}
Derived(int n) :Base(n)
{
Base btemp(-n);
b = btemp;
cout << "Derived::Derived(" << n << ")" << endl;
}
};
int main(void)
{
Derived d(3); //Base 클래스가 먼저 생성되고 Derived 클래스가 생성되는 과정에서 디폴트 Base 클래스 생성자가 호출된 다음에(상속을 받았으므로)
//Base(-3) 클래스가 생성되고 Derived(3) 클래스가 생성된다
return 0;
}
개발 환경:Visual Studio 2017
지적, 조언, 질문 환영입니다! 댓글 남겨주세요~
[참고] 기초를 탄탄히 세워주는 C++ 프로그래밍 입문 황준하 저
'C++ > 기초를 탄탄히 세워주는 C++ 프로그래밍 입문(황준하 저)' 카테고리의 다른 글
기초를 탄탄히 세워주는 C++ 프로그래밍 입문 11장 연습문제 (0) | 2017.07.10 |
---|---|
기초를 탄탄히 세워주는 C++ 프로그래밍 입문 10장 연습문제 (0) | 2017.07.07 |
기초를 탄탄히 세워주는 C++ 프로그래밍 입문 8장 연습문제 (0) | 2017.07.04 |
기초를 탄탄히 세워주는 C++ 프로그래밍 입문 7장 연습문제 (0) | 2017.07.03 |
기초를 탄탄히 세워주는 C++ 프로그래밍 입문 6장 연습문제 (0) | 2017.07.02 |