12. 클래스의 상속(6) - 상속과 동적 메모리 대입

WanJu Kim·2022년 12월 15일
0

C++

목록 보기
54/81

만약 기초 클래스에 동적 할당이 있고 복사 생성자, 대입 연산자가 있으면 파생 클래스에 어떤 영향을 미칠까? (프로그래머의 머리가 깨지는 영향?)

  • case 1: 파생 클래스가 new를 사용하지 않음.
// 기초 클래스.

class baseDMA
{
private:
	char* label;
	int rating;
public:
	baseDMA(const char* l = "null", int r = 0);
	baseDMA(const baseDMA& rs);
	virtual ~baseDMA();
	baseDMA& operator=(const baseDMA& rs);
};

위의 기초 클래스에는 동적 할당 변수, 복사 생성자, 대입 연산자가 있다.

class lacksDMA : public baseDMA
{
private:
	char color[40];
public:
	...
};

그 기초 클래스를 상속받는 파생 클래스가 있다. 이 파생 클래스에는 뭐 동적 할당 받을 것도 없고 다른 특별한 게 없다고 생각해보자. 이런 경우에는 명시적 파괴자, 복사 생성자, 대입 연산자를 만들어야 할까? 대답은 NO. 그럼 왜? 일단 파생 클래스에서는 뭐 동적 할당 같은 거 하는 게 없다. 그러니 디폴트 파괴자면 충분하다. 또한 파생 클래스에 특별한(?) 변수가 없기 때문에 파생 클래스는 디폴트 복사 생성자로 충분하다. 그럼 기초 클래스는? 기초 클래스를 복사 할 때는 알아서 기초 클래스의 복사 생성자가 실행된다. 대입 연산자도 이와 마찬가지로 생각하면 된다.

  • case 2: 파생 클래스가 new를 사용한다.
class lacksDMA : public baseDMA
{
private:
	char * style;
public:
	...
};

이런 경우에는 당연히 명시적 파괴자, 복사 생성자, 대입 연산자를 정의해주어야 한다. 파괴자는 각각의 클래스에 동적 메모리를 할당하는 변수를 해제해주면 된다.

lacksDMA::~lacksDMA()
{
	delete[] style;
}

baseDMA::~baseDMA()
{
	delete[] label;
}

주의할 것은 파생 클래스의 복사 생성자에 기초 클래스 복사 생성자를 써주어야 한다. 기초 클래스의 private 멤버에 파생 클래스가 접근할 수 없기 때문이다.

lacksDMA::lacksDMA(const lacksDMA& lacks)
    : baseDMA(lacks)
{
	...
}

여기서 기초 클래스의 매개변수로 파생 클래스를 사용했는데, 문제 없다. 왜? 기초 클래스는 파생 클래스 참조를 참조 할 수 있기 때문이다. 대입 연산자도 마찬가지로 기초 클래스를 호출해주어야 한다. 왜? 파생 클래스뿐만 아니라 기초 클래스도 같이 대입해야 하기 때문이다.

lacksDMA& lacksDMA::operator=(const lacksDMA& ls)
{
    if (this == &ls)
        return *this;
    baseDMA::operator=(ls);	// 기초 클래스 대입 연산자.
    delete[] style;
    style = new char[std::strlen(ls.style) + 1];
    strcpy_s(style, std::strlen(ls.style) + 1, ls.style);
    return *this;
}

생성자가 아닌 함수라 코드 블럭에서 호출해주었다.

profile
Question, Think, Select

0개의 댓글