문제

나는 문구는 이 형식의 예를 더 명확합니다.

말 나는 벡터의 동물을 가고 싶을 통해 배열을 참조하는 경우 요소가 두 개 또는 고양이?

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 기능 DogCat 재정의하고,컴파일러는 자동적으로 호출됩니다.

(또한, dynamic_cast 은 상대적으로 느리게,그래서 그들이 너무 많은 것을 방해하는 성능반면 가상 함수 호출이 일반적인 단지 하나의 명령입니다.)

Are you sure you want to do that?무엇을 할 것인지 정확히 반대의 다형성,그리고 다형성에서 가장 좋은 방법입니 객체 지향 프로그래밍입니다.

느슨하게 말하기:뭔가 하지 않으면 는 경우에 당신은 동물은 개;동물이 계층 구조를 알 때 무엇을 하나의 그 개체 개입니다!:)

당신이 정말로 필요한 경우여 귀사의 애플리케이션 수준을 식별하는 개 vs non-개 사용하지 않도록 해야 합온(dynamic_casttypeid고),그 지식을 명시적으로 귀하의 클래스 계층 구조입니다.

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 니다.그러나 어떤 사용 typeiddynamic_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 한 파생된 형식도 작동하지만,문자열을 설명 그것은 더 낫다).

단순히는 또 다른 옵션입니다.

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top