私はこのコードを試しました:
class A
{
virtual void foo() = 0;
};
class B
{
virtual void foo() = 0;
};
class C : public A, public B
{
//virtual void A::foo(){}
//virtual void B::foo(){}
virtual void A::foo();
virtual void B::foo();
};
void C::A::foo(){}
void C::B::foo(){}
int main()
{
C c;
return 0;
}
コメント部分を使用する場合は問題ありませんが、クラス宣言の外部に定義を書き込もうとすると、コンパイラーがエラーを報告します。私はMSVC11コンパイラを使用していますが、これを書く方法を知っている人はいますか?コードをcppファイルに移動する必要があります。
ありがとう~~
関数は、名前とパラメータータイプに基づいて、基本クラスの仮想関数をオーバーライドします(以下を参照)。したがって、クラスC
にはtwo仮想関数foo
があり、1つは各A
とB
から継承されます。ただし、関数void C::foo()
は両方をオーバーライドします:
[class.virtual]/2
仮想メンバー関数
vf
がクラスBase
およびクラスDerived
で宣言され、Base
から直接または間接的に派生した場合、同じ名前のメンバー関数vf
、parameter-type-list、cv-qualification 、および_Base::vf
_としてのref-qualifier(または同じものがない)が宣言されている場合、_Derived::vf
_も仮想(宣言されているかどうかに関係なく)であり、オーバーライド _Base::vf
_。
コメントですでに述べたように、[dcl.meaning]/1は、(メンバー)関数の宣言でqualified-idを使用することを禁じています。
declarator-idが修飾されている場合、宣言は、修飾子が参照するクラスまたは名前空間の以前に宣言されたメンバーを参照するものとします[...] "
したがって、virtual void X::foo();
はC
内の宣言としては違法です。
コード
_class C : public A, public B
{
virtual void foo();
};
_
aFAIKがfoo
をオーバーライドする唯一の方法であり、_A::foo
_と_B::foo
_の両方をオーバーライドします。 _A::foo
_と_B::foo
_に2つの異なるオーバーライドを設定して、別の継承レイヤーを導入する以外に、動作を変える方法はありません。
_#include <iostream>
struct A
{
virtual void foo() = 0;
};
struct B
{
virtual void foo() = 0;
};
struct CA : A
{
virtual void foo() { std::cout << "A" << std::endl; }
};
struct CB : B
{
virtual void foo() { std::cout << "B" << std::endl; }
};
struct C : CA, CB {};
int main() {
C c;
//c.foo(); // ambiguous
A& a = c;
a.foo();
B& b = c;
b.foo();
}
_
仮想関数は1つだけですfoo
:
class A {
virtual void foo() = 0;
};
class B {
virtual void foo() = 0;
};
class C : public A, public B {
virtual void foo();
};
void C::foo(){}
void C::A::foo(){}
void C::B::foo(){};
int main() {
C c;
return 0;
}
私は同じ問題に踏み込み、誤って2番目のスレッドを開きました。そのために残念。私のために働いた1つの方法は、多重継承なしでそれを解決することでした。
#include <stdio.h>
class A
{
public:
virtual void foo(void) = 0;
};
class B
{
public:
virtual void foo(void) = 0;
};
class C
{
class IA: public A
{
virtual void foo(void)
{
printf("IA::foo()\r\n");
}
};
class IB: public B
{
virtual void foo(void)
{
printf("IB::foo()\r\n");
}
};
IA m_A;
IB m_B;
public:
A* GetA(void)
{
return(&m_A);
}
B* GetB(void)
{
return(&m_B);
}
};
秘訣は、多重継承を使用するのではなく、インターフェイス(AおよびB)から派生したクラスをローカルクラス(IAおよびIB)として定義することです。さらに、このアプローチは、必要に応じて、多重継承を使用して不可能な、各インターフェースの複数の実現を持つオプションも開きます。ローカルクラスIAとIBは、クラスCへのアクセスを簡単に許可できるため、インターフェイスIAとIBの両方の実装でデータを共有できます。
各インターフェイスへのアクセスは、次のように実行できます。
main()
{
C test;
test.GetA()->foo();
test.GetB()->foo();
}
...そしてfooメソッドに関するあいまいさはもうありません。