C++ 向派生类传递指针或引用,以便调用基类方法
我有一个派生类和一个基类,它们都重写同一个虚函数。如何向其他函数传递指向派生类实例的指针或引用,但仍然调用基类版本的虚函数C++ 向派生类传递指针或引用,以便调用基类方法,c++,inheritance,interface,C++,Inheritance,Interface,我有一个派生类和一个基类,它们都重写同一个虚函数。如何向其他函数传递指向派生类实例的指针或引用,但仍然调用基类版本的虚函数 我的问题似乎与你的正好相反。实际上,我希望对派生对象进行切片,使其看起来像一个基础对象(假设我可以安全地这样做),但却不知道如何进行切片 我有一个庞大的数据集,复制成本很高,因此我转而传递一个轻量级的视图对象,它允许迭代。我有一个接口,不同的数据集继承该接口,以显示它们可以提供视图: class data_interface { virtual view get_
我的问题似乎与你的正好相反。实际上,我希望对派生对象进行切片,使其看起来像一个基础对象(假设我可以安全地这样做),但却不知道如何进行切片 我有一个庞大的数据集,复制成本很高,因此我转而传递一个轻量级的
视图对象,它允许迭代。我有一个接口,不同的数据集继承该接口,以显示它们可以提供视图
:
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,上述内容已被精简-在这里,直接获取视图
参数更有意义,但在上下文中,我将组合多个数据集,其中一个数据集需要拥有存储,而不仅仅是查看存储)
当我试图用另一个需要进行额外处理的数据集扩展基本数据集时,问题就出现了。下面是一个派生类:
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());
}
};
我想要发生的是,由于某个进程
被传递一个对base\u owns\u data
的引用,因此base\u owns\u data::get\u view()
将在某个进程
中调用
实际发生的情况是,某些进程仍然调用派生的\u拥有的\u数据::get\u view()
。当这两个函数相互调用时,就会产生一个无限循环
我不知道该怎么办-我无法从界面中删除virtual
,否则界面将变得无用。我也不想复制数据。但是我不知道如何强制base\u owns\u data::get\u view()
对类型为derived\u owns\u data
的引用进行调用
我尝试传递指针而不是引用,但这似乎仍然会导致无限循环
如何安全地使派生类在some\u进程中显示为基类
完整MCVE(或打开):
必须从基类显式调用重写函数:
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;
}
不能对现有对象进行切片。这意味着改变它的类型。从派生类型复制到基类型时会发生对象切片。也许这可以通过以下方法解决?关于多态性,对象的实际类型不同于用于引用它的类型。使用virtual
函数的目的是确保派生类型的行为正确,即使它是通过指针或对其基类型之一的引用来引用的。将引用或指针强制转换为基类型不会改变调用哪个virtual
函数,因为这将完全违背多态性的目的。我从未想过用引用自己的(明显的)类型来限定对引用的调用-谢谢!
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;
}