对泛型函数使用继承

Using Inheritance for Generic Functions

本文关键字:继承 函数 泛型      更新时间:2023-10-16

我试图创建一个模板类,其中包含多个覆盖模板方法的子类(我相信我这样做是正确的)。然后,我想要一个可以处理所有子节点的函数。

例如:

#include <iostream>
using namespace std;
class base{
public:
    virtual void print(void){
        cout << "Base" << endl;
    }
};
class inherit_a : public base{
public:
    virtual void print(void) override{
        cout << "inherit_a" << endl;
    }
};
class inherit_b : public base{
public:
    virtual void print(void){
        cout << "inherit_b" << endl;
    }
};
void print_function(base item){
    item.print();
}

int main(){
    inherit_a item_a;
    print_function(item_a);
    return(0);
}

像我期望的那样打印"基",但是如果inherit_b被输入到print_function,我希望它使用inherit_a的打印方法或inherit_b的打印方法。这样的事情可能发生吗?

你正在寻找的是所谓的亚型多态性;在c++中,只有引用类型允许多态virtual函数调用按预期工作。你可以使用引用:

void print_function(base& item){
    item.print();
}

或指针:

void print_function(base* item){
    item->print();
}

您所做的是通过值传递对象,仅复制对象的base部分—这称为切片:

void print_function(base item){
    item.print();
}

注意,由于print()成员函数不修改对象,它可以而且应该声明为const。此外,参数列表中的(void)是C风格的,在c++中是冗余的;用()代替。

virtual void print() const {
    cout << "Base" << endl;
}

const是签名的一部分,所以子类也必须指定它:

virtual void print() const override {
    cout << "inherit_a" << endl;
}

那么print_function()可以接受const对象的引用:

void print_function(const base& item){
    item.print();
}

或指向const对象的指针:

void print_function(const base* item){
    item->print();
}

说明print_function()也不修改它的参数

这里的问题是您正在将base值转换为print_function。即使你传递一个inherit_a实例,它也会导致创建一个类型为base的新对象(称为对象切片)。在print_function运行时,它不再是inherit_a值,因此不会调用派生方法。

你正在寻找的是对base的引用,以防止切片并允许值保持其原始类型

void print_function(base& item){
  item.print();
}

"这是可能的吗?"-是的,这叫做多态性