【问题标题】:Can functions accept abstract base classes as arguments?函数可以接受抽象基类作为参数吗?
【发布时间】:2012-03-08 11:58:18
【问题描述】:

在熟悉了基本类和封装的概念后,我开始着手理解多态性,但我不知道如何让它发挥作用。我搜索过的许多示例都被认为是真的,真的强制(类 Foo 和 Bar 对我来说太抽象了,看不到实用程序),但这是我对基本概念的理解:你编写一个基类,从中派生一大堆其他东西来改变基本方法的内容(但不是它们“是”什么),然后你可以编写通用函数来接受和处理任何派生类,因为您已经在某种程度上标准化了它们的外观。在这个前提下,我尝试像这样实现基本的 Animal->cat/dog 层次结构:

class Animal {
  public:
    virtual void speak() = 0;
};

class Dog : public Animal {
  public:
    void speak() {cout << "Bark bark!" << endl;}
};

class Cat : public Animal {
  public:
    void speak() {cout << "Meow!" << endl;}
};

void speakTo(Animal animal) {
    animal.speak();
}

speakTo 可以带的地方可以带一种一般的动物,让它说话。但据我了解,这不起作用,因为我无法实例化 Animal(特别是在函数参数中)。那么我问,我是否了解多态性的基本用途,我该如何真正做我尝试做的事情?

【问题讨论】:

    标签: c++ inheritance polymorphism abstract-class


    【解决方案1】:

    您不能将Animal 对象传递给派生类函数,因为您不能创建Animal 类的对象等等,它是一个抽象类
    如果一个类包含至少一个纯虚函数(speak()),那么该类将成为一个抽象类,您不能创建它的任何对象。但是,您可以创建指针或引用并将它们传递给它。 您可以传递一个Animal 指针或对该方法的引用。

    void speakTo(Animal* animal) 
    {
        animal->speak();
    }
    
    int main()
    {
        Animal *ptr = new Dog();
        speakTo(ptr);
    
        delete ptr;   //Don't Forget to do this whenever you use new()
        return 0;
    }
    

    【讨论】:

    • 啊,太棒了!我读过“指向派生类的指针与指向其基类的指针类型兼容”,但我陷入了按引用传递与实际传递指针的关系。传递指针是否与 PBR 完全不同,或者 PBR 的 & 符号只是通知编译器特殊处理语法(如果这有意义的话......)?
    • @connorG:引用不会接受 null,否则它们几乎相同
    • @ConnorG:嗯,在Distinguish between pointers & references 中,没有比 Scott Meyers 更好地回答你的问题。请注意,为了简单起见,我在示例中使用了指针。
    【解决方案2】:

    您需要传递参考而不是副本:

    void speakTo(Animal& animal) {
        animal.speak();
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2018-08-04
      • 1970-01-01
      • 2013-10-26
      • 2019-08-12
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多