당신은 아마 Bird
같은 계층 구조를하지 않고 Bat
당신이에서 제공하는 하위 클래스에 선언 fly()
방법없이 Animal
에서 발생한다. 그렇게하면 통일 된 계층 구조의 포인트를 잃어 버리게됩니다.
는 당신도 할 수있다 :
class Animal {
virtual bool canFly() { return false; }
virtual void fly() {throw Exception("Sorry babe, I don't fly"); }
}
그리고 Bird
및 Bat
에 fly
우선합니다.
이렇게하면 개가 아닌 고양이에게 fly()
메서드가 구현됩니다.
class Flyer : public Animal {
virtual void fly() = 0;
}
class Bat : public Flyer {}
class Bird : public Flyer {}
Reptile
, Mammal
같은 더 자세한 생물학적 분류와 일치하지 않을 것이다 : 그래서 어쩌면 당신은이 방법을 선언 할 새로운 클래스 Flyer
를 만들 수 있습니다.
또 다른 속임수는 move()
과 같은 메서드를 제안 할 수 있으며 개는 run()
및 bird를 fly()
으로 구현하며 모두 통합 된 인터페이스를 사용합니다.
다른 점은 개가 날 수 있는지 여부를 묻는 질문이 유효하다고 생각하므로 Dog.canFly()
과 같은 메소드를 동물의 일부로 구현해야한다고 생각합니다.
이 나는이에 가고 싶어, 고려 모든 :
// Your base animal
class Animal {
virtual bool canFly() {return false;}
};
// Any animal that could fly, just abstract class
class Flyer {
virtual void fly() = 0;
}
// Ants, flies etc.; real biological hierarchy
class Insect : public Animal {}
class Mammals : public Animals {}
class Birds : public Animals {}
// And now flying bird :
class Bird : public Birds, public Flyer {
virtual bool canFly() {return true; }
virtual void fly() {...}
}
// And flying insect
class Fly : public Insect, public Flyer {
virtual bool canFly() {return true; }
virtual void fly() {...}
}
그리고 당신은 다음 (난 당신이 이것에 대한 포인터를 사용해야합니다 것을 두려워 this answer 기준) 할 수 있습니다 :
if(Collection[i]->canFly()){
Flyer *thisBird = static_cast<Flyer*>(Collection[i]);
}
는 또한 Animal
에서 Flyer
을 유도하고 가상 상속을 사용하지만, 이것은 "공포의 다이아몬드"이라고하며 not considered good practice하지만, 읽는 가치가 있었다.
바와 같이 canFly()
을 지정해야합니다 코멘트에서 Ricibob, Flyer
지적하는 것입니다 간단한 예 :
class Flyer {
public:
virtual bool canFly() const {return true;}
virtual void fly() {cout << "Flying" << endl; }
};
Bird b;
cout << "Can fly: " << b.canFly() << endl;
// Error 1 error C2385: ambiguous access of 'canFly'
하지만 Animal
에서 제공 Flyer
을하고 수업 Birds
의 Bird
일부 경우 Flyer
:
class Animal {
public:
virtual bool canFly() const {return false;}
};
class Flyer : virtual Animal {
public:
virtual bool canFly() const {return true;}
virtual void fly() {cout << "Flying" << endl; }
};
class Bird : virtual public Birds, virtual public Flyer {
};
// Warning 1 warning C4250: 'Bird' : inherits 'Flyer::Flyer::canFly' via dominance
지금 canFly()
은 1
을 반환하지만 코드가 잘못되었습니다. 이 시점에서
... 당신은 수동으로 각각의 서브 클래스 (또는 대형 그룹)에 대한
canFly()
을 지정하거나 (
Chicken
예를 바로하지 않은)
Flyers
에서
Birds
을 제공하거나, 새로운 서브 클래스 제공 :
을
class FlyingBrids : public Birds, public Flyer /* Flyer not delivered from Animal */ {
virtual bool canFly() const {return true;}
};
Fly
이 Insect
에서 전달되므로 Flyer
이 여전히 중요하다는 점에 유의하십시오. 당신이 개를 주문하면
virtual void move(){}
virtual void fly(){}
그것은 아무것도하지 않고 비행 :
컨테이너 내에서 값으로 * 다형 적으로 사용하기 쉬운 개체를 넣을 것입니다. 그 [잘 끝나지 않을 것입니다] (http://stackoverflow.com/questions/274626/what-is-the-slicing-problem-in-c). – Jon
각 동물원의'Collection' 벡터는 그 안에 (generic, bird, bat 중 하나와 같은 종류의) 동물을 가지고 있습니다.캐스팅하지 않으면 어떻게해야하는지에 대한 제안 사항이 있습니까? – tiswas
'동물'이란 무엇입니까? – juanchopanza