2017-08-10 88 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