将指针或引用传递给派生类,以便调用基类方法

时间:2018-02-15 21:20:02

标签: c++ inheritance interface

我有一个派生类和一个基类,它们都覆盖相同的虚函数。如何将一个其他函数传递给派生类的实例的指针或引用,但仍然调用基类的虚函数版本?

我似乎与this question完全相反。我实际上想要切割我的派生对象,使它看起来像一个基础对象(假设我可以安全地这样做),但无法弄清楚如何做到这一点。

我有一大堆复制成本很高的数据,所以我改为传递一个允许迭代的轻量级view对象。我有一个接口,各种数据集继承,以宣传他们可以提供view

class data_interface
{
    virtual view get_view() = 0;
};

有一个基类拥有其中一个数据集,并可根据要求提供视图:

class base_owns_data : public data_interface
{
public:
    view get_view() override
    {
        return view(d);
    }

private:
    data d;
};

这个课程孤立无援。我的应用程序通过引用自由函数来传递它,以便获得更复杂的数据视图:

view some_process(base_owns_data &b)
{
    auto working_view = b.get_view();
    // Do a bunch of things to filter the view
    return working_view;
}

(请注意,上面的内容被删除了MCVE - 在这里,直接采用view参数会更有意义,但在上下文中我将组合几个数据集,其中一个需要拥有存储,而不仅仅是查看它)

当我尝试使用另一个需要进行额外处理的基础数据集扩展时,会出现问题。这是派生类:

class derived_owns_data : public base_owns_data
{
public:
    base_owns_data& as_base()
    {
        return *this;
    }

    view get_view() override
    {
        return some_process(this->as_base());   
    }
};

我想要发生的是,由于some_process传递了对base_owns_data的引用,base_owns_data::get_view()将在some_process中调用。

实际发生的是some_process仍然调用derived_owns_data::get_view()。这导致无限循环,因为这两个函数来回互相调用。

我不知道该怎么做 - 我无法从界面中删除virtual,或者界面变得无用。我也不想复制数据。但是我无法弄清楚如何强制base_owns_data::get_view()derived_owns_data类型的引用上调用。

我尝试传递指针而不是引用,但这似乎仍然会导致无限循环。

如何安全地使派生类看起来是some_process中的基类?

完整MCVE(或在ideone上):

struct data
{
    char c[100];
};

class view
{
public:
    view(data d) :
        first(&d.c[0]),
        last(&d.c[100])
    {

    }
private:
    char * first;
    char * last;
};

class data_interface
{
    virtual view get_view() = 0;
};

class base_owns_data : public data_interface
{
public:
    view get_view() override
    {
        return view(d);
    }

private:
    data d;
};

view some_process(base_owns_data &b)
{
    return b.get_view();
}

class derived_owns_data : public base_owns_data
{
public:
    base_owns_data& as_base()
    {
        return *this;
    }

    view get_view() override
    {
        return some_process(this->as_base());   
    }
};


int main() {
    derived_owns_data d;
    d.get_view();
    return 0;
}

1 个答案:

答案 0 :(得分:3)

您必须从基类显式调用overriden函数:

Connect to alien server ('localhost', 10000),
Then send USER followed by aliensignal,
Then send PASS followed by unlockserver,
Next SEND followed by moonbase.
Then send END and if all followed key will provided.