【问题标题】:Using Inheritance for Generic Functions对泛型函数使用继承
【发布时间】:2013-03-09 02:05:36
【问题描述】:

我正在尝试创建一个包含多个子级的模板类,这些子级覆盖模板的方法(我相信我这样做是正确的)。然后我想要一个可以与所有孩子一起使用的函数。

例如:

#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_a 的打印方法或inherit_b 的打印方法,如果inherit_b 被估算为print_function。这样的事情可能吗?

【问题讨论】:

    标签: c++ inheritance


    【解决方案1】:

    你要找的东西叫做子类型多态;在 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() 也没有修改它的论点。

    【讨论】:

    • 非常感谢,也感谢您提供有关 const 的更多信息。我能够让一切正常工作。
    【解决方案2】:

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

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

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

    【讨论】:

      【解决方案3】:

      “这样的事情可能吗?” - 是的,它叫polymorphism

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2018-12-22
        • 1970-01-01
        相关资源
        最近更新 更多