2017-08-10 89 views
0

我有這套類。簡單示例中的C++多態性

class Animal { 
public: 
    Animal(uint32_t attr1, uint32_t attr2); 

    virtual uint32_t get_attr1() const; 
    virtual uint32_t get_attr2() const; 

private: 
    uint32_t attr1; 
    uint32_t attr2; 
}; 

class Dog: public Animal { 
public: 
    Dog(uint32_t attr1, uint32_t attr2, uint32_t attr3); 
    uint32_t get_attr3() const; 

private: 
    uint32_t attr3; 
}; 

class Cat: public Animal { 
public: 
    Cat(uint32_t attr1, uint32_t attr2, uint32_t attr4); 
    uint32_t get_attr4() const; 

private: 
    uint32_t attr4; 
}; 

現在我想有一個聲明

vector<Animal*> animals; 

和幾個功能如下:

void f(Dog* dog); 
void f(Cat* cat); 

和驗證碼:

for (auto animal: animals) { 
    f(animal); 
} 

如何使多態性出這個代碼?它看起來像動物不像貓或狗一樣對待。

+0

爲什麼你要處理一個指向矢量的指針?另外,'f'函數應該是'cat'和'dog'類的成員。 – scohe001

+0

我不希望f函數因設計選擇而成爲類的成員。同意指針雖然 – tomtom

+1

如果你這樣做,然後看看[dynamic_cast](http://en.cppreference.com/w/cpp/language/dynamic_cast) – scohe001

回答

4

設置f()過載,將Animal*作爲輸入,然後您的for循環將按照您所寫的那樣工作。爲了然後調用單獨f()重載DogCat,你將不得不在運行時使用dynamic_cast,如:

void f(Dog* dog) 
{ 
    // do something only a dog can do ... 
} 

void f(Cat* cat) 
{ 
    // do something only a cat can do ... 
} 

void f(Animal *animal) 
{ 
    if (Dog *dog = dynamic_cast<Dog*>(animal)) { 
     f(dog); 
    } 
    else if (Cat *cat = dynamic_cast<Cat*>(animal)) { 
     f(cat); 
    } 
} 

... 

for (auto animal: animals) { 
    f(animal); 
} 

然而,這不利於多態性的原則。如果f()需要做取決於它被稱爲上的Animal類型不同的東西,它應該是Animal類的虛方法,然後根據需要繼承者可以覆蓋它:

class Animal { 
public: 
    ... 
    virtual ~Animal() {} // <-- don't forget this! 
    ... 
    virtual void f() = 0; 
}; 

class Dog: public Animal { 
public: 
    ... 
    void f() override; 
}; 

class Cat: public Animal { 
public: 
    ... 
    void f() override; 
}; 

void Dog::f() 
{ 
    // do something only a dog can do ... 
} 

void Cat::f() 
{ 
    // do something only a cat can do ... 
} 

... 

for (auto animal: animals) { 
    animal->f(); 
} 
+0

還有[訪客模式](https://stackoverflow.com/documentation/design-patterns/4579/visitor-pattern/15127/visitor-pattern-example-in-c#t=201708110127395809679)以避免添加許多虛擬方法。 – Jarod42