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

标签 c++ inheritance interface

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


我的问题似乎与 this question 完全相反.我实际上想分割我的派生对象,使其看起来像一个基础对象(假设我可以安全地这样做),但不知道如何去做。

我有大量数据,复制起来成本很高,因此我传递了一个允许迭代的轻量级 view 对象。我有一个接口(interface),各种数据集继承来宣传它们可以提供 view:

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

有一个基类拥有这些数据集之一,并且可以根据请求提供对其的 View :

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,否则界面将变得无用。我也不想复制数据。但我无法弄清楚如何强制在 derived_owns_data 类型的引用上调用 base_owns_data::get_view()

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

如何安全地使派生类在 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;
}

最佳答案

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

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

关于c++ - 将指针或引用传递给派生类,以便调用基类方法,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/48816466/

相关文章:

java - 您可以将 Java 集合编程为一个接口(interface)并使用 Serializable 吗?

c++ - 如何将C++异常处理程序与C库完美结合?

cocoa-touch - 在扩展中添加便利的初始值设定项并在子类上调用它们

Android- (button.Click += event;) 和 (button.SetOnClickListener(this)) 之间有什么区别?

带有抽象继承错误的Spring Autowired

Java : Inheritance and Basic Design Optimization

c++ - 记录接口(interface)

C++ 指向二维数组的指针

c++ - 重载运算符 []

c++ - 为什么 Visual C++ 自动矢量化器不矢量化这个简单的循环?