我有一个派生类和一个基类,它们都覆盖了同一个虚函数。如何向其他函数传递一个指针或对派生类实例的引用,但仍然调用基类版本的虚函数?
我的问题似乎与 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/