C++
명품 C++ 5장 8번
NUMERO_K
2018. 10. 31. 19:55
8. 문제 7번의 MyIntStack를 수정하여 다음과 같이 선언하였다. 스택에 저장할 수 있는 정수의 최대 개수는 생성자에서 주어지고 size 멤버에 유지한다. MyIntStack 클래스를 작성하라.
소스코드
#include <iostream>
using namespace std;
class MyIntStack {
int *p; // 스택 메모리로 사용할 포인터
int size; // 스택의 최대 크기
int tos; // 스택의 탑을 가리키는 인덱스
public:
MyIntStack();
MyIntStack(int size);
MyIntStack(MyIntStack &s); // 복사 생성자
~MyIntStack();
bool push(int n); // 정수 n 푸시. 꽉 차 있으면 false, 아니면 true 리턴
bool pop(int &n); // 팝하여 n에 저장. 스택이 비어 있으면 false, 아니면 true 리턴
};
MyIntStack::MyIntStack() {
tos = -1;
size = 1;
p = new int[size];
}
MyIntStack::MyIntStack(int size) {
tos = -1;
this->size = size;
p = new int[size];
}
MyIntStack::MyIntStack(MyIntStack &s) {
this->size = s.size;
this->tos = s.tos;
this->p = new int[s.size];
for (int i = 0; i < s.tos; ++i)
this->p[i] = s.p[i];
}
MyIntStack::~MyIntStack() {
if (p)
delete[] p;
}
bool MyIntStack::push(int n) {
if (tos == (size-1)) return false;
else {
++tos;
p[tos] = n;
return true;
}
}
bool MyIntStack::pop(int& n) {
if (tos == (-1)) return false;
else {
n = p[tos];
--tos;
return true;
}
}
int main() {
MyIntStack a(10);
a.push(10);
a.push(20);
MyIntStack b = a; // 복사 생성
b.push(30);
int n;
a.pop(n); // 스택 a팝
cout << "스택 a에서 팝한 값 " << n << endl;
b.pop(n); // 스택 b팝
cout << "스택 b에서 팝한 값 " << n << endl;
}
실행결과
클래스가 포인터 멤버 변수를 가지고 있는 겨우, 원본 객체의 포인터 멤버 변수가 사본 객체의 포인터 멤버 변수에 복사되면, 이 둘은 같은 메모리를 가리키게 되어 문제가 일어납니다.
소멸자에서 조건문을 쓰지 않으면 이미 반환환 메모리를 다시 반환하므로, 비정상 종료가 일어납니다.