C++ 多重继承指定所需的虚拟函数而不重新定义它
我想知道是否有一种方法可以指定在多重继承中,一个基类虚拟函数成为单个虚拟定义。我看到的唯一方法是在派生类中编写此函数的显式定义,并显式调用其中一个基类。这很麻烦,我希望C++ 多重继承指定所需的虚拟函数而不重新定义它,c++,c++11,C++,C++11,我想知道是否有一种方法可以指定在多重继承中,一个基类虚拟函数成为单个虚拟定义。我看到的唯一方法是在派生类中编写此函数的显式定义,并显式调用其中一个基类。这很麻烦,我希望使用可能会有所帮助,但事实并非如此 例如,在下面的代码中,我必须定义一个C::value,即使我只想转发到class B版本。难道没有更简单的方法吗 #include <iostream> using namespace std; struct A { virtual char const * value(
使用
可能会有所帮助,但事实并非如此
例如,在下面的代码中,我必须定义一个C::value
,即使我只想转发到class B版本。难道没有更简单的方法吗
#include <iostream>
using namespace std;
struct A
{
virtual char const * value() const
{ return "A"; }
};
struct B
{
virtual char const * value() const
{ return "B"; }
};
class C : public A, public B
{
public:
//using B::value;
virtual char const * value() const
{ return B::value(); }
};
int main()
{
C obj;
cout << obj.value() << endl;
A * ptr = &obj;
cout << ptr->value() << endl;
}
#包括
使用名称空间std;
结构A
{
虚拟字符常量*value()常量
{返回“A”;}
};
结构B
{
虚拟字符常量*value()常量
{返回“B”;}
};
C类:公共A、公共B
{
公众:
//使用B::value;
虚拟字符常量*value()常量
{返回B::value();}
};
int main()
{
C obj;
cout多重继承非常罕见,编写这样一个函数的成本非常低,不值得一个语言特性,我当然知道没有一个提供这样的功能
使用
唯一影响的是可见性,这不是这里的问题,因此它肯定不会有任何帮助
我认为唯一能做到这一点的方法就是写一个明确的
这个函数在派生类中…,我希望使用may
帮助
在您的上下文中使用
关键字仅用于将名称带入当前范围(用于防止名称隐藏)。假设您请求的功能已经存在。现在查看以下修改的代码:
struct A
{
virtual char const * value() const
{ return "A"; }
void value (double); // new function
};
class C : public A, public B
{
public:
using B::value;
void value(int); // new function
};
假设我们有与C
中的value(int)
和A
中的value(double)
同名的函数。这两个函数与virtual value()
无关,它们与C
的对象一起使用
如何将A::value(double)
与C
的对象一起使用?当然,您必须在C
的主体中使用A::value;。因此,作为副作用,我们有2个虚拟的函数匹配:A::value()const
和B::value()const
!
使用A*
或B*
调用时选择哪个
这只是一个例子,但也可能存在其他问题。无论您在问题中提到什么,都是获得正确结果的最佳方式。它明确表示C::value()const
是B::value()的包装const
否。除了使用二进制范围解析运算符显式调用函数外,没有其他方法可以执行此操作::
最好将接口方法设置为非虚拟方法。下面的代码将帮助您实现所需的功能。但是,输出会有所不同。我相信这是应该的。
代码可以找到
输出:
B
A
#包括
使用名称空间std;
结构A
{
字符常量*值()常量
{
返回值impl();
}
受保护的:
虚拟字符常量*valueImpl()常量
{返回“A”;}
};
结构B
{
字符常量*值()常量
{
返回值impl();
}
受保护的:
虚拟字符常量*valueImpl()常量
{返回“B”;}
};
C类:公共A、公共B
{
公众:
使用B::value;
};
int main()
{
C obj;
cout上述程序的输出是什么?也许您可以向继承树中添加一个虚拟“节点”(例如,DummyC
,它实际上继承自a
,而C
则继承自DummyC
和B
)。不确定这是否可行,但请看这里:看看这是否有帮助。@Bingo,上面的程序输出“B”和“B”,因为我重写了函数。如果不这样做,只需使用
declaration执行,您将得到“B”和“a”。@Asaf,这给了我一个想法,可能只是粘贴“值”在一个没有构造函数的虚拟实例化继承的基类中。这可能是可行的。@ AsAF,我的想法不起作用,它仍然需要一个最终的重写器。虽然你的VISILBILITY注释是正确的,但是我不认为多重继承是罕见的。事实上,如果这种模式得到支持,它可能会更普遍。另外,像Py这样的语言。THON和Ruby可以做这样的事情,所以它不能被完全打折,因为“不值得”。为什么不?其他的语言完全无关。“值得”是“C++中的C++委员会的意见”。。Ruby或Python在哪里?没有。大多数程序员明智地避免了MI,与MI所遭受的其他问题的海洋以及简单地定义一个简单的转发函数的简单解决方案相比,这绝对是一个微不足道的下降。输入法,混音绝非罕见。我不想要输出“B”“a”,我想要“B”“B”,应该只有一个value()
为结果对象定义并可访问。
#include <iostream>
using namespace std;
struct A
{
char const* value() const
{
return valueImpl();
}
protected:
virtual char const * valueImpl() const
{ return "A"; }
};
struct B
{
char const* value() const
{
return valueImpl();
}
protected:
virtual char const * valueImpl() const
{ return "B"; }
};
class C : public A, public B
{
public:
using B::value;
};
int main()
{
C obj;
cout << obj.value() << endl;
A * ptr = &obj;
cout << ptr->value() << endl;
}