final
- 상속 안 해줄꺼야!
- 상속을 맊을 방법이 없음, 어떤 클래스든 상속을 해 갈 수 있음.
- solution 1)
class Animal final
{
public:
virtual void SetWeight(int weight);
};
// final 키워드 때문에 더 이상 Animal 클래스를 상속 받을 수 없음.
class Dog : public Animal // 에러
{
public:
virtual void SetWeight(int weight);
};
// 왠만한 클래스에서는 기본적으로 final 을 쓰는것이 맞을 수도 있음.
// 다른 사람이 내 클래스를 어떻게 가져다 사용 할 지 모른다.
// Animal 클래스는 final이 아님.
class Dog final : public Animal
{
public:
virtual void SetWeight(int weight) override;
}
class Corgi : public Dog // 에러
{
}
// 함수의 상속 막기
class Animal
{
public:
virtual void SetWeight(float weight) final;
}
class Dog : public Animal
{
public:
virtual void SetWeight(int weight) override;// 에러
Dog();
~Dog();
}
// 함수를 재 정의 할 수 없음.
- final 키워드
- 클래스나 가상 함수를 파생 클래스에서 오버라이딩 못 하도록 하려면 final 키워드를 사용
- 컴파일 도중에 확인함.
- 당연히 가상 함수가 아니면 쓸 수 없음.
override
class Animal
{
public:
virtual void SetWeight(float weight);
}
class Dog : public Animal
{
public:
virtual void SetWeight(int weight); // 실수로 int를 사용.
// Animal::SetWeight(float weight) 를 오버라이딩하지 않음.
// 실수를 알아채기 어려움.
}
// 이 문제는 때론 치명적일 수 있다.
// Animal 클래스에서 float이 double로 바뀐다면 Animal클래스를 상속 받은
// 모든 클래스를 일일이 대조하며 고쳐야 한다.
- solution - override 키워드 사용
class Animal
{
public:
virtual void SetWeight(float weight);
}
class Dog : public Animal
{
public:
virtual void SetWeight(int weight) override; <- 컴파일 에러로 실수를 알려줌.
}
class Animal
{
public:
virtual void SetWeight(float weight);
void PrintAll();
}
class Dog : public Animal
{
public:
virtual void SetWeight(float weight) override;// OK
virtual void SetWeight(int weight) override;// 컴파일 에러
void PrintAll() override;// 컴파일 에러, 가상 함수가 아님.
}
- override 키워드
- 잘못된 가상 함수 오버라이딩을 막으려면 override 키워드를 사용
- 당연히 가상 함수가 아니면 쓸 수 없음
- 이것도 컴파일 도중에 검사.
- Ex) final/override
class Human
{
public:
// 생성자에서 초기화 할 필요 없음, 이름 없이 개체 생성하기 싫음.
Human() = delete;
Human(const char* name);
// 기본 소멸자를 사용, 뭔가 동적 메모리를 할당하지 않는다라고 추측 가능.
virtual ~Human() = default;
virtual void SayMyName() const;
protected:
std::string mName;
};
class Pope final : public Human
{
public:
Pope();
Pope(const Pope& otherPope) = delete;
// 부모 클래스의 소멸자가 virtual인것을 보장하고 기본 소멸자 생성
virtual ~Pope() override = default;
virtual void SayMyName() const override;
// Compile error
// void Scream() const override;
};
// Compile error
/*class PopeClone : public Pope
{
public:
PopeClone();
virtual ~PopeClone() override = default;
virtual void SayMyName() const override;
};*/
Human* human = new Human("Johny");
human->SayMyName();
Human* human2 = new Pope();
human2->SayMyName();
Pope pope;
// Compile Error
// Pope popeClone(pope);
delete human2;
delete human;