0. 과제 설명
아래는 프로젝트 기능의 주요 키워드이며,
각각의 키워드마다 해결해야하는 과제, 모르겠는 부분을 적어놓았다.
1. Virtual (다형성)
상속 관계에서 play()함수에 virtual을 사용해 객체마다 다른 출력문이 나오도록
static 변수 count가 LegalDVD가 생성될 때 DVD도 거쳐서, count++ 코드가 두 번 실행되었다.
그래서 만들어진 객체의 개수보다 더 많아지는 것을 알 수 있었고,
count 의 증가는 가장 상위 클래스에 한번만 해주면 되는 것이었다.
2. 연산자 오버로딩 **
(1) ostream 오버로딩
(2) = 오버로딩
(3) + 오버로딩
오버로딩 시 delete 과정에서 Dangling Pointer 관련한 에러가 나올 수 있다.
3. 클래스 상속
UML 다이어그램에서 중복 상속을 추가.
이때 상속은 public 상속으로 (이유 하단에 기재할 것)
4. static 멤버 변수
객체 생성 시 static 멤버 변수인 count가 1씩 증가되도록
초안
#include "Media.h"
#include "DVD.h"
#include "LegalDVD.h"
#include "VTR.h"
#include <iostream>
using namespace std;
// 주석점수 10점
// 보고서 점수 20점
// static int count값을 0으로 초기화 (10점)
int Media::count = 0;
int main(void)
{
Media* mp[4];
// new 할때마다 count증가하도록 구현 (10점)
mp[0] = new VTR("Hello", 15, "avi");
mp[1] = new DVD("Superman", 3, "123-9899");
mp[2] = new LegalDVD("Marvel", 10, "456-9899", "GG entertainment");
mp[3] = new VTR("Disney", 23, "mkv");
for (int i = 0; i < Media::count; i++) // 다형성 구현 (20점)
mp[i]->play();
cout << "연산자 오버로딩 실습" << endl;
cout << mp[0]; // "VTR이 play되고 있습니다."가 출력되도록 연산자 5오버로딩 구현(30점)
// mp[3]는 포인터 자료형
mp[3] = *mp[1] + mp[2]; //"mp[1]의 length+mp[2]의 length”가 되게끔 오버로딩 (30점)
cout << mp[3]->getLength() << endl; // 출력값은 13
for (int i = 0; i < 4; i++)
delete mp[i];
return 0; // new한 객체들이 잘 소멸되는지 보일 것 (20점)
}
문제는 mp[3] = *mp[1] + mp[2]에서 발생했다.
#include "Media.h"
#include <iostream>
#include <string>
using namespace std;
Media::Media(string title, int length)
: title(title), length(length)
{
count++;
}
Media::~Media() {}
void Media::setLength(int length)
{
this->length = length;
}
void Media::setTitle(string title)
{
this->title = title;
}
int Media::getLength() {
return length;
}
string Media::getTitle() {
return title;
}
void Media::play () const{
cout << "Can't play" << endl;
}
Media* Media::operator+(const Media* mp)
{
this->length += mp->length;
cout << "this의 title은" << this->getTitle() << endl; // this는 mp[1]
return this;
}
// mp = *mp[1] + mp[2]
Media& Media::operator=(const Media *mp)
{ // 매개변수에는 mp[1]이 들어오게 된다.
setLength(mp->length);
return *this;
}
ostream& operator<<(ostream& output, const Media* media)
{
media->play();
return output;
}
문제는 + 연산자 오버로딩에서 발생했다고 생각한다.
mp[1]을 담고 있는 this를 리턴하여 mp[3] 포인터 변수에 대입함으로써,
mp[1]의 주솟값을 mp[3]의 포인터 변수에 담게된다.
(이때 mp[1]의 length는 update된 상태이다. )
이렇게 되면 mp[3] 포인터 변수가 mp[3] 뿐만 아니라 mp[1]을 동시에 가리키게 되어서, delete시 이미 delete된 mp[1]이 다시 delete되는 dangling이 생긴다.
그래서 delete 과정에서 문제가 생긴 것
Media& Media::operator=(const Media *mp)
{ // 매개변수에는 mp[1]이 들어오게 된다.
setLength(mp->length);
delete mp;
return *this;
}
나는 = 연산자 오버로딩 과정에서 매개변수로 들어온 객체 mp (실제로 main함수에서는 + 연산자 오버로딩의 결과로 리턴된 mp[1] 객체) 에 대한 포인터 연결을 끊어줌으로써 이 문제를 해결하고자 하였다.
그런데 두번째 문제는, 위 함수를 main함수의
이 부분에서 호출 하지 못하고, 저 대입 연산자(=) 는 Shallow Copy가 되는 문제가 생겼다.
즉, 정의해놓은 저 연산자 오버로딩이 실행되지 않아 delete 코드도 실행되지 않았고,
+ 연산자 오버로딩에서 발생한 Dangling Pointer 문제도 해결되지 못하였다.
이에 따라 main함수에서 + 오버로딩을 하는 과정을 바꾸는 시도를 할 수 있었는데,
해결 방법을 두 가지로 나누어 보았다.
(1) 임의의 변수를 만들어서, + 연산자오버로딩 시 this가 아닌 temp 객체를 리턴하기
(2) main함수에서 mp[3]의 주솟값을 temp 포인터 변수에 잠시 담아두었다가,
mp[3]의 내부 멤버 변수 length의 값이 바뀌게 되면(목적 달성) 다시 mp[3]의 주소를 temp의 주소로 치환한다.
'Major Study > Object Oriented Programming' 카테고리의 다른 글
객체지향 프로그래밍2 상속, 연산자 오버로딩, 다형성, 템플릿 관련 의문점 정리 및 해결 (2) | 2021.06.15 |
---|---|
C++ template 내용 정리(열혈 C++, 강의노트, 기타 자료 참고) (0) | 2021.06.15 |
객체지향 프로그래밍2 기말고사 대비 문제 wirte-up (0) | 2021.06.14 |
객체지향 프로그래밍 프로젝트 (상속과 다형성, 가상함수) 해결 과정 / 가상 함수, 다형성 개념 정리 (0) | 2021.05.31 |
2021 객체지향 프로그래밍 중간고사 대비 (0) | 2021.04.17 |