25.06.02 (2) - C++ 문법 1주차

김영하·2025년 6월 2일

C++

목록 보기
16/32

게임 개발자를 위한 C++ 문법 1주차

마무리로 나오는 1주차 과제를 해결.


핸드폰 브랜드 특징 출력 프로그램

다형성상속의 개념을 이해하고,
반복문을 활용하여 다양한 핸드폰 브랜드와 그 특징을 출력하는 프로그램을 작성하세요.

  • 메인함수 실행시 아래와 같이 출력 되어야 합니다.
Samsung
Galaxy S 시리즈
Apple
iPhone Pro 시리즈
Xiaomi
Redmi Note 시리즈
  • 전체 코드의 구조는 아래와 같습니다.

  • 참고용 코드 뼈대

#include <iostream>
using namespace std;

// TODO: Phone 클래스 구현
// - displayBrand()와 showFeature() 순수 가상 함수를 포함하도록 구현하세요
// - 소멸자를 반드시 virtual로 선언하세요

// Samsung 클래스 작성 (Phone 클래스를 상속받음)
class Samsung : public Phone {
public:
    void displayBrand()   {
        cout << "Samsung" << endl;
    }
    void showFeature()  {
        cout << "Galaxy S 시리즈" << endl;
    }
};

// pple 클래스 작성 (Phone 클래스를 상속받음)
class Apple : public Phone {
public:
    void displayBrand()  {
        cout << "Apple" << endl;
    }
    void showFeature()  {
        cout << "iPhone Pro 시리즈" << endl;
    }
};

// Xiaomi 클래스 작성 (Phone 클래스를 상속받음)
class Xiaomi : public Phone {
public:
    void displayBrand() {
        cout << "Xiaomi" << endl;
    }
    void showFeature() {
        cout << "Redmi Note 시리즈" << endl;
    }
};

int main() {
    // TODO: main 함수 구현
    // - Phone* 타입의 배열을 생성하여 Samsung, Apple, Xiaomi 객체를 저장
    // - 반복문을 사용하여 각 객체의 displayBrand()와 showFeature()를 호출
    // - 반복문을 사용하여 메모리 해제를 위해 delete 호출
    return 0;
}

1) 1단계 구현
(선언부 헤더 / 정의부 소스 파일 구분 안하고 한 파일로)

#include <iostream>
#include <string>

using namespace std;

class Phone {
public:
	Phone() {};

	virtual void displayBrand() = 0;
	virtual void showFeature() = 0; // 순수가상함수

	virtual ~Phone() {};
};

class Samsung : public Phone {
public:
	Samsung() {};

	void displayBrand() {
		cout << "Samsung" << endl;
	}

	void showFeature() {
		cout << "Galaxy S 시리즈" << endl;
	}

	/* 파생 클래스에도 소멸자를 넣어주고 싶을 때
	기본 클래스에 소멸자를 virtual 줘서 가상 소멸자로 만드는 것 같은데
	굳이 파생 클래스에 소멸자 재정의 안해줘도 동작하는지 실험 */
	
};

class Apple : public Phone {
public:
	/* 뼈대 코드에는 파생 클래스에 생성자가 없어서
	없어도 문제없는지 실험 */

	void displayBrand() {
		cout << "Apple" << endl;
	}

	void showFeature() {
		cout << "iPhone Pro 시리즈" << endl;
	}
};

class Xiaomi : public Phone {
public:
	void displayBrand() {
		cout << "Xiaomi" << endl;
	}

	void showFeature() {
		cout << "Redmi Note 시리즈" << endl;
	}
};

int main() {
	Samsung s;
	Apple a;
	Xiaomi x;

	Phone* ptrArr[3] = {&s, &a, &x};
	for (Phone* i : ptrArr) {
		i->displayBrand();
		i->showFeature();
		delete i;
	}

	return 0;
}

우선 구동했을 때 에러가 나면서 화면이 넘어갔는데,
아마 실험 삼아 파생 클래스에는 소멸자 정의를 안해줬기 때문에
delete i; 소멸자 호출에서 문제가 생겨서로 추정된다.

Samsung 부분까지만 나오고 멈췄다


2) 2단계 구현

#include <iostream>
#include <string>

using namespace std;

class Phone {
public:
	Phone() {};

	virtual void displayBrand() = 0;
	virtual void showFeature() = 0; // 순수가상함수

	virtual ~Phone() {};
};

class Samsung : public Phone {
public:
	Samsung() {};

	void displayBrand() {
		cout << "Samsung" << endl;
	}

	void showFeature() {
		cout << "Galaxy S 시리즈" << endl;
	}

	virtual ~Samsung() {};
	
};

class Apple : public Phone {
public:
	/* 뼈대 코드에는 파생 클래스에 생성자가 없어서
	없어도 문제없는지 실험 */

	void displayBrand() {
		cout << "Apple" << endl;
	}

	void showFeature() {
		cout << "iPhone Pro 시리즈" << endl;
	}

	virtual ~Apple() {};
};

class Xiaomi : public Phone {
public:
	void displayBrand() {
		cout << "Xiaomi" << endl;
	}

	void showFeature() {
		cout << "Redmi Note 시리즈" << endl;
	}

	virtual ~Xiaomi() {};
};

int main() {
	Samsung s;
	Apple a;
	Xiaomi x;

	Phone* ptrArr[3] = {&s, &a, &x};
	for (Phone* i : ptrArr) {
		i->displayBrand();
		i->showFeature();
		delete i;
	}

	return 0;
}

파생 클래스들에도 virtual 소멸자를 달아줬음에도 같은 에러가 뜨는 상황
"중단점 명령 실행됨" 이라는 오류가 나온다

여전히 소멸자 관련해서 문제가 있는 것으로 보인다


3) 3단계 구현

#include <iostream>
#include <string>

using namespace std;

class Phone {
public:
	Phone() {};

	virtual void displayBrand() = 0;
	virtual void showFeature() = 0; // 순수가상함수

	virtual ~Phone() {};
};

class Samsung : public Phone {
public:
	Samsung() {};

	void displayBrand() {
		cout << "Samsung" << endl;
	}

	void showFeature() {
		cout << "Galaxy S 시리즈" << endl;
	}

	~Samsung() {};
	
};

class Apple : public Phone {
public:
	/* 뼈대 코드에는 파생 클래스에 생성자가 없어서
	없어도 문제없는지 실험 */

	void displayBrand() {
		cout << "Apple" << endl;
	}

	void showFeature() {
		cout << "iPhone Pro 시리즈" << endl;
	}

	~Apple() {};
};

class Xiaomi : public Phone {
public:
	void displayBrand() {
		cout << "Xiaomi" << endl;
	}

	void showFeature() {
		cout << "Redmi Note 시리즈" << endl;
	}

	~Xiaomi() {};
};

int main() {
	Phone* ptrArr[3] = {new Samsung(), new Apple(), new Xiaomi()};
	for (Phone* i : ptrArr) {
		i->displayBrand();
		i->showFeature();
		delete i;
		// i = nullptr;
	}

	return 0;
}

여전히 문제가 있는 거 같은데(vs 가 잠깐 빨개짐) 결과 출력까지는 정상적으로 된다

new 는 동적할당 관련 내용으로,
"중단점 명령" 해결방안을 찾다가 delete 와 같이 나와서 사용해봤다.
미리 객체를 생성해두고 & 참조를 사용하는 거 보다
포인터 배열 사용에 있어서는 이 방식이 더 유효한 것 같다.

i = nullptr; 부분은 이전 코드에서
i 하나가 먼저 소멸하면서 비어가지고 문제가 생기는 거 같아서
nullptr로 채워주는 느낌으로 넣어둔 코드인데,
지금 new 를 사용한 매커니즘에선 필요는 없다. (없어도 동작함)
이 부분 때문에 잠깐 빨개질 수도 있다는데 결론적으론 문제가 없다고 한다.

동기화 이슈 등 다른 문제로도 빨개질 수 있음

  • 추가로,
    파생 클래스에서 생성자/소멸자 에 특별한 동작이 없다면 구현 안해줘도 된다고 한다.
profile
내일배움캠프 Unreal 3기

0개의 댓글