#include <iostream>
#include <sstream>
class VeryBase {
protected:
int a_;
public:
VeryBase() : a_(1) {}
virtual operator std::string() {
return "0";
}
};
class Base1 : public virtual VeryBase {
protected:
int b_;
public:
Base1() : b_(2) {}
operator std::string() {
return "1";
}
};
class Base2 : public virtual VeryBase {
protected:
int c_;
public:
Base2() : c_(3) {}
operator std::string() {
return "2";
}
};
class TargetClass : public Base1, public Base2 {
protected:
int d_;
public:
TargetClass() : d_(4) {}
operator std::string() {
std::ostringstream s;
s << a_ << ' ' << b_ << ' ' << c_ << ' ' << d_ << std::endl;
return s.str();
}
};
int main()
{
VeryBase* a = new TargetClass;
Base1* b = dynamic_cast<Base1*>(a);
Base2* c = dynamic_cast<Base2*>(a);
std::cout << std::string(*a) //1 2 3 4
<< std::string(*b) //1 2 3 4
<< std::string(*c) //? ? ? ?
<< std::endl;
}
私はこのようなコードを持っています。Windows 8 の MSVC 2012 x64、Ubuntu 12.10 および 13.04 の g++ 4.7 および Clang++ 3.2 (x86 と x64 の両方) で期待どおりに動作します。ただし、疑問符のある行は、MinGW 4.7 x86 でコンパイルすると未定義の動作を示します。または MinGW 4.8 x64(申し訳ありませんが、私はそう思っていました)。
デバッガーの出力は、その時点で TargetClass の vtable へのリンクに問題があることを示しています。ブレークポイントを配置すると、TargetClass::operator string() が不適切に逆参照されたオブジェクトでロードされていることがわかります。ただし、明示的な dynamic_cast を配置すると、正しい出力が得られます。
何がこの問題を引き起こす可能性があるのだろうか。MinGW のバグであれば、C++ のコア コンセプトの 1 つを壊すため、おそらくすぐに解決されるでしょう。