仮想メソッドを適切にオーバーライドしています。私はいくつかのコンストラクタを連結し、基本クラスのコンストラクタで私は仮想メソッドを呼び出します。以下のようにC++仮想メソッドが期待通りに呼び出されない
コールチェーンは次のようになります。
B(p)->A(p)->B.foo(p)
コールチェーンは、C++である:
B(p)->A(p)->A.foo(p)
コールチェーンは、C#である:他の言葉でそう
B(p)->A(p)->B.foo(p)
、中C#の動作は期待通りですが、Cではそうではありません。
C++コード:
#include <cstdio>
class A {
public:
A();
A(int);
virtual void foo(int s);
};
class B : public A {
public:
B();
B(int s) : A(s) {};
virtual void foo(int s) override;
};
A::A() {
std::printf("A\r\n");
};
A::A(int s) : A() {
std::printf("A: %d\r\n", s);
foo(s);
};
void A::foo(int s) {
std::printf("A::foo(%d)\r\n", s);
}
B::B() : A(){
std::printf("B\r\n");
};
void B::foo(int s) {
std::printf("B::foo(%d)\r\n", s);
}
int main(int argc, char* argv[]) {
B b(2);
}
出力:
A
A: 2
A::foo(2)
C#コード:
using System;
namespace demo {
class A{
public A() {
Console.WriteLine("A");
}
public A(int s) : this(){
Console.WriteLine("A: " + s.ToString());
foo(s);
}
public virtual void foo(int s) {
Console.WriteLine(string.Format("A:foo({0})", s));
}
}
class B : A{
public B() : base() {
Console.WriteLine("B");
}
public B(int s) : base(s) {
}
public override void foo(int s) {
Console.WriteLine(string.Format("B:foo({0})", s));
}
}
static class Run {
static void Main() {
new B(2);
}
}
}
出力:
A
A: 2
B::foo(2)
クラスBのオーバーライドされたメソッドがC++で呼び出されないのはなぜですか?正しく上書きする必要がありますか?
仮想ディスパッチは、コンストラクタが終了するまで機能しません。 – Arunmu
http://stackoverflow.com/questions/962132/calling-virtual-functions-inside-constructors – tia
あなたはC++とC#の出力が同じだと言いました。 C#でB :: foo(2)を呼び出すのですか? – Zebrafish