如何避免继承中的冲突 在我的C++程序中,我有两个类(B1和B2),它们有自己的方法,但有1个(“意外”)。例如:

如何避免继承中的冲突 在我的C++程序中,我有两个类(B1和B2),它们有自己的方法,但有1个(“意外”)。例如:,c++,inheritance,multiple-inheritance,C++,Inheritance,Multiple Inheritance,B1类标题: void height(); void size(); void enabled(); B2类标题: void width(); void length(); void enabled(); 现在我有一个从B1和B2继承的类a。由于多重继承之后,我在方法enabled()中出现了“冲突”,我如何避免这种情况?有没有办法从继承中排除方法?例如,我可以从类B1中排除enabled()继承(我不能将其设置为私有,因为它是从其他派生自B1的类中使用的)。还有其他想法吗?您可以尝试使用名

B1类标题:

void height();
void size();
void enabled();
B2类标题:

void width();
void length();
void enabled();

现在我有一个从B1和B2继承的类a。由于多重继承之后,我在方法
enabled()
中出现了“冲突”,我如何避免这种情况?有没有办法从继承中排除方法?例如,我可以从类B1中排除
enabled()
继承(我不能将其设置为私有,因为它是从其他派生自B1的类中使用的)。还有其他想法吗?

您可以尝试使用名称空间。使
B1::enabled()
成为名为
X
B2::enabled()
-
Y
的命名空间的成员。在派生类中,使用
X::enabled()
Y::enabled()

可以尝试使用名称空间。使
B1::enabled()
成为名为
X
B2::enabled()
-
Y
的命名空间的成员。在派生类中,使用
X::enabled()
Y::enabled()
可以使用语法
class::function
消除对基类方法的调用的歧义。在您的情况下,无论您在何处使用
enabled
,请确认呼叫:

B1::enabled();
B2::enabled();
如果您只需要其中一个函数,则可以编写using声明:

using B1::enabled;

您可以使用语法
class::function
消除对基类方法的调用的歧义。在您的情况下,无论您在何处使用
enabled
,请确认呼叫:

B1::enabled();
B2::enabled();
如果您只需要其中一个函数,则可以编写using声明:

using B1::enabled;

您可以解决歧义,但无论如何都将继承这两个函数。您无法选择不继承某些函数。要修复歧义,请使用以下命令:

class B1
{
public:
    void height();
    void size();
    void enabled();
};

class B2
{
public:
    void width();
    void length();
    void enabled();
};

class A: public B1, public B2
{
public: 
    using B2::enabled;
};

您可以解决歧义,但无论如何都将继承这两个函数。您无法选择不继承某些函数。要修复歧义,请使用以下命令:

class B1
{
public:
    void height();
    void size();
    void enabled();
};

class B2
{
public:
    void width();
    void length();
    void enabled();
};

class A: public B1, public B2
{
public: 
    using B2::enabled;
};

就我个人而言,我会将B封装在A中,并为A中提供的任何有用的接口提供一个外部所需的接口,而不是继承。如果您需要多态行为,请使A和B都从同一个抽象接口继承。

我个人会将B封装在A中,并为A中提供的任何有用的接口提供一个外部接口,而不是继承。如果需要多态行为,请使A和B都从同一个抽象接口继承。

1)不要执行多重继承2)不要使用相同的方法命名。此外,IIRC编译器在出现歧义时会发出警告。请参阅:和@m0skit0:但假设类A应实现方法height()、size()、width()和length()。如何避免多重继承?此外,不同的名称(例如B1::enabled()和B2::isEnabled()可能会造成混淆。您可以始终使用接口(虚拟方法)和组合而不是继承,如Java/C#do。这就是为什么不鼓励多重继承,除了多重继承/实现“接口”(完全抽象类)。你几乎可以肯定地重新考虑这个问题。一种可能是
A
应该“包装”
B1
B2
的实例。问问你自己,
A
“是否真的是一个“
B1
A
”也是一个“
B2
?”1)不做多重继承2)方法的名称不一样。此外,IIRC编译器在出现歧义时会发出警告。请参阅:和@m0skit0:但假设类A应实现方法height()、size()、width()和length()。如何避免多重继承?此外,不同的名称(例如B1::enabled()和B2::isEnabled()可能会造成混淆。您可以始终使用接口(虚拟方法)和组合而不是继承,如Java/C#do。这就是为什么不鼓励多重继承,除了多重继承/实现“接口”(完全抽象类)。你几乎可以肯定地重新考虑这个问题。一种可能是
A
应该“包装”
B1
B2
的实例。问问你自己,
A
“真的是一个”
B1
A
“也是一个”
B2
?我不知道使用
keyword@ABCplus在这种情况下,它“拖动”<代码> B2::启用到 < < /代码>类,使它成为唯一考虑A对象调用的候选对象。在这样的上下文中总是使用它来解决歧义。
使用
适用于c++11,如果没有它,您可以定义
A::enabled()
并调用
B1::enabled()
B2::enabled()
或两者都显式调用。@Slava,这
使用
与c++11无关。它老多了feature@ixSci嗯,你说得对,总有一些事情我记不清:(我不知道使用
keyword@ABCplus,在这种情况下,它会“拖”<代码> B2::启用< <代码> A/<代码>类,使它成为唯一考虑A对象的候选对象。它总是在这样的上下文中用来解决歧义。<代码>使用 C++ 11的工作,如果您没有定义,则可以定义<代码>:::()<代码>,并调用<代码> B1::Enabess()<代码>或<代码> B2:::
或两者都明确。@Slava,这个
使用的
与C++11没有任何关系。它要旧得多feature@ixSci嗯,你说得对,总有一些事情我记不清:(