문제
나는 문구는 이 형식의 예를 더 명확합니다.
말 나는 벡터의 동물을 가고 싶을 통해 배열을 참조하는 경우 요소가 두 개 또는 고양이?
class Dog: public Animal{/*...*/};
class Cat: public Animal{/*...*/};
int main()
{
vector<Animal*> stuff;
//cramming the dogs and cats in...
for(/*all elements in stuff*/)
//Something to the effect of: if(stuff[i].getClass()==Dog) {/*do something*/}
}
제가 희망하는 일종의 명확합니다.나는에 대해 알고 포인터를 사용 하 여 수신하지만,아직 풀지 못한 개체를 비교하고 싶을 만들지 않는 개체는 경우 내가 할 수 있습니다.
는 방법이 있을까요?미리 감사드립니다.
해결책
으로 다른 사람들은 주목해야 합도를 사용하여 typeid
, 도 dynamic_cast
연산자를 얻을 동적인 유형의 포인터.가상 기능을 만든 이를 방지하기 위해 종류의 불결함.
어쨌든 여기에 당신이 무엇을 하는 경우 말 하고 싶다(참고 참조는 반복기를 줄 것이다 당신 Animal*
.그래서 만약 당신 **it
을 얻을 것이다 Animal&
):
for(std::vector<Animal*>::iterator it = v.begin(); it != v.end(); ++it) {
if(typeid(**it) == typeid(Dog)) {
// it's a dog
} else if(typeid(**it) == typeid(Cat)) {
// it's a cat
}
}
참고 적용할 수 있습니다 typeid
운전자 형태 그 자체로 다음과 같다.당신이 필요하지 않 객체를 만듭니다.또한 참고 포인터를 사용 하 여 수신 방법으로 작동하지 않는 경우에 당신은 그것을 전달하는 포인터가 처럼 typeid(*it)
.를 사용하여 그것을 같이 줄 것이다 당신은 단지 typeid(Animal*)
지 않는 유용합니다.
비슷 dynamic_cast
사용될 수 있습니다:
for(std::vector<Animal*>::iterator it = v.begin(); it != v.end(); ++it) {
if(Dog * dog = dynamic_cast<Dog*>(*it)) {
// it's a dog (or inherited from it). use the pointer
} else if(Cat * cat = dynamic_cast<Cat*>(*it)) {
// it's a cat (or inherited from it). use the pointer.
}
}
참고는 두 가지 경우 모두에서,당신의 동물이 유형이어야 한 변이.는 것을 의미가 있어야 합 또는 상속에서 적어도 하나의 가상 기능입니다.
다른 팁
당신이 사용할 수 있는 dynamic_cast
, 만큼,이 벡터를 포함한 동물의 포인터.
vector <Animal *> stuff;
for(int i=0;i<stuff.size();i++) {
Dog *pDog = dynamic_cast <Dog *> (stuff[i]);
if(pDog) {
// do whatever with the dog
}
Cat *pCat = dynamic_cast <Cat *> (stuff[i]);
if(pCat) {
// and so on
}
}
그러나 당신이 알고 있어야 한다는 이것은 일반적으로 가장하지 않습니다.당신이 시도해야와 함께 작동 다형성에 대한하지 않습니다.다시 말해서,작성하려고 가상 Animal
기능 Dog
고 Cat
재정의하고,컴파일러는 자동적으로 호출됩니다.
(또한, dynamic_cast
은 상대적으로 느리게,그래서 그들이 너무 많은 것을 방해하는 성능반면 가상 함수 호출이 일반적인 단지 하나의 명령입니다.)
Are you sure you want to do that?무엇을 할 것인지 정확히 반대의 다형성,그리고 다형성에서 가장 좋은 방법입니 객체 지향 프로그래밍입니다.
느슨하게 말하기:뭔가 하지 않으면 는 경우에 당신은 동물은 개;동물이 계층 구조를 알 때 무엇을 하나의 그 개체 개입니다!:)
당신이 정말로 필요한 경우여 귀사의 애플리케이션 수준을 식별하는 개 vs non-개 사용하지 않도록 해야 합온(dynamic_cast
고 typeid
고),그 지식을 명시적으로 귀하의 클래스 계층 구조입니다.
for (size_t i = 0; i != v.size(); ++i) {
if (v[i]->isDog()) { v->cleanupPoop(); }
}
거기에 몇 가지 작은 성능 이점이 있지만,주요 혜택은 노출에 필요한 행동은 클래스 인터페이스 유지보수 프로그래머를 위한 것입니다.온(되는 것으로 한정으로 이)필요하지 않기 위해서는 클래스 계층구조하는 기능입니다.
지금 함께 다른 어떤 사람은 말했다,그것을 가능성이 높 isDog()
수로 리팩터링 하지 않는 무언가의 지식이 필요로 하는 전체 계층 구조면(등 needsPoopCleanup()
).다른 사람들처럼 말했다,당신이 당신의 혜택은 다형성하는 경우 응용 프로그램 논리를 조건에 따라 실행에 따라 개체 유형이 있습니다.
사용할 수 있습니다 typeid
운영자 이를 위해,예를 들어,
if (typeid(stuff[i].getClass())==typeid(Dog))
이 잡을 수 없는 경우에 그 파생의 클래스 Dog
, 니다,하지만.사용할 수 있습니다 dynamic_cast
니다.그러나 어떤 사용 typeid
나 dynamic_cast
은 자주 나타내는 디자인 결함이 있다.일반적으로,당신은 당신이 필요하지 않은 무엇인지 알고 파생된 형식,그리고 거기에 아마 더 나은 방법을 포함한 다형성이다.그것의 하드하는 올바른 조언을 제공없이 실제 예를 들어,하지만.
사용 가능:
으로 표시하여 다른 사람의 응답을 사용하여 가상 기능을 수시로 실제적으로 충분히입니다"C++"스스로의 생각을 가지고 있습니다.여기서의 예를 사용하여 가상 기능:
#include<iostream>
#include<vector>
using namespace std;
/////////////
class Animal {
public:
virtual void move() { cout << "animal just moved" << endl; }
};
class Dog : public Animal {
public:
void move() { cout << "dog just moved" << endl; }
};
class Cat : public Animal {
public:
void move() { cout << "cat just moved" << endl; }
};
void doSomethingWithAnimal(Animal *a) {
a->move();
}
/////////////
int main() {
vector<Animal*> vec;
vector<Animal*>::iterator it;
Animal *a = new Animal;
Dog *d = new Dog;
Cat *c = new Cat;
vec.push_back(a);
vec.push_back(d);
vec.push_back(c);
it = vec.begin();
while( it != vec.end() ) {
doSomethingWithAnimal(*it);
it++;
}
return 0;
}
이 충분하지 않습니다,그 다음 다른 사람들이 이미 게시 답변을 실제로 사용 조건 논리는 대신 중합 논리입니다.
수락 응답이 올바른지만,당신이 알고 있어야 하는 또 다른 옵션뿐만 아니하는 언급되지 않은.할 수 있는 가상의 기능 동물 등"이라는 형식()"는 반환할 수 있습 int 또는 문자열(또는 유형을 비교).
그래서 예를 들어:
class Animal {
/*...*/
public:
virtual std::string type() const { return "animal"; }
};
class Dog: public Animal{
/*...*/
public:
virtual std::string type() const { return "dog"; }
};
class Cat: public Animal{
/*...*/
public:
virtual std::string type() const { return "cat"; }
};
이 방법은 당신이 그렇게만 할 수 있다:
if(array[i]->type() == "dog") { }
형식 기능을 반환 할 수 있습니다 아무것도(int 한 파생된 형식도 작동하지만,문자열을 설명 그것은 더 낫다).
단순히는 또 다른 옵션입니다.