函数可以接受抽象基类作为参数吗?

Posted

技术标签:

【中文标题】函数可以接受抽象基类作为参数吗?【英文标题】: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(特别是在函数参数中)。那么我问,我是否了解多态性的基本用途,我该如何真正做我尝试做的事情?

【问题讨论】:

【参考方案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();

【讨论】:

以上是关于函数可以接受抽象基类作为参数吗?的主要内容,如果未能解决你的问题,请参考以下文章

如何将子类作为期望基类的函数的参数传递,然后将该对象传递给指向这些抽象类对象的指针向量?

是否可以通过引用以基类作为参数的函数来传递派生类

在以抽象基类为参数的函数中将指针和赋值运算符与派生类一起使用

带有接受派生类参数的基类参数的成员函数指针

基类和子类函数名相同且参数类型一样,基类函数如何被覆盖,还存在吗?存在何处?请详细回答,谢谢~~~~

将参数传递给基类构造函数