다형성
- virtual 없으면 다형성이 안된다.
- 포인터 타입이 아니라 실제 객체 타입 기준으로 실행된다
#include <iostream>
#include <vector>
using namespace std;
class Animal
{
public:
Animal() {}
virtual ~Animal() {}
virtual void speak()
{
cout << "'Animal' cannot make a sound.\n";
}
};
class Dog :public Animal
{
void speak()
{
cout << "Woof\n";
}
};
class Cat :public Animal
{
void speak()
{
cout << "Meow\n";
}
};
int main() {
vector<Animal*> zoo{ new Dog, new Cat, new Animal };
for (auto p : zoo) p->speak(); // Woof / Meow / ???
for (auto p : zoo) delete p;
}
깊은 복사
- 새로운 메모리를 별도로 할당한 뒤 그 안에 값을 복사
- 하나의 객체가 해제되도 다른 객체는 해제되지 않는다
#include <iostream>
using namespace std;
class IntPtr {
int* ptr;
public:
IntPtr(int val) {
ptr = new int(val);
}
~IntPtr()
{
delete ptr;
ptr = nullptr;
}
IntPtr(const IntPtr& other)
{
if (this == &other)
{
return;
}
int* newPtr;
newPtr = new int(*other.ptr);
ptr = newPtr;
}
int getValue() const {
return *ptr;
}
};
int main() {
IntPtr p1(10);
IntPtr p2 = p1; // 복사 생성자 호출
cout << p1.getValue() << "\n"; // 10
cout << p2.getValue() << "\n"; // 10
}
복사 생성자에서는 자기 자신 비교가 일반적으로 필요하지 않다는 점도 배웠다
아래의 코드는 사용하지 않는다.
if (this == &other)
{
return;
}
정리
- 포인터 멤버를 가진 클래스는 기본 복사에만 맡기면 위험할 수 있다.
- 깊은 복사를 위해서는 새로운 메모리를 직접 할당해야 한다.
- 동적 할당을 사용했따면 소멸자까지 함께 고려해야 한다.
- 복사 생성자는 객체가 복사되는 순간 호출된다.
마무리
다향성
- 단순히 함수를 상속받는 것이 아닌 같은 인터페이스로 다른 동작을 수행할 수 있다는 점에서 객체지향 설계의 중요성을 체감할 수 있었다.
깊은 복사
- C++에서 메모리 관리가 왜 중요한가를 알게 해주는 문제였다. 단순히 값이 잘 출력된다고 끝이 아니라, 객체가 복사되고 소멸되는 과정까지 함께 고려해야 안전한 코드가 된다는 점을 확인할 수 있었다.
'학습일지 > C와 C++' 카테고리의 다른 글
| C++ 예외 처리의 심층 이해와 실무적 고찰 (0) | 2026.04.27 |
|---|---|
| C++ 문자열 아나그램 최소 변경 횟수 (0) | 2026.04.06 |
| vector 중복 제거 구현 및 개선 과정 (0) | 2026.04.02 |
| C++ 팀 프로젝트 TextConsoleRPG (0) | 2026.04.01 |
| C++ 콘솔 RPG 프로젝트 Main 흐름 정리 (0) | 2026.03.31 |