[英]pure virtual functions overloading and covariant return types with multiple inheritance
[英]MSVC: Covariant Return Types And Virtual Inheritance
我不确定这是 Visual-C++ 编译器中的错误还是未定义的行为。
struct DummyBase { virtual ~DummyBase() = default; };
struct DummyDerived : virtual public DummyBase {};
只是一个类和一个使用虚拟继承的派生类
DummyDerived derived;
DummyBase* base = &derived;
std::cout << "Derived : " << &derived << std::endl;
std::cout << "Base : " << base << std::endl;
将DummyDerived*
为DummyBase*
,指针会发生偏移。 这似乎是由虚拟继承引起的:
Derived : 00000000002CF838
Base : 00000000002CF840
即使指针值不同,比较也会返回 true:
std::cout << "IsSame : " << (base == &derived) << std::endl << std::endl;
输出:
IsSame : 1
到现在为止还挺好。
问题出现在以下设置中:
struct IBaseReturner
{
virtual DummyBase* Get() = 0;
};
struct IDerivedReturner : public virtual IBaseReturner
{
virtual DummyDerived* Get() = 0;
};
struct BaseReturner : public virtual IBaseReturner
{
};
struct DerivedReturner : public BaseReturner, public virtual IDerivedReturner
{
DummyDerived* Ptr;
virtual DummyDerived* Get() override { return Ptr; }
};
这里我们有接口和类的实现,这些类的方法返回DummyBase
或DummyDerived
通过协变返回类型覆盖。 再次使用虚拟继承。
// Setup
DerivedReturner returner;
returner.Ptr = &derived;
IBaseReturner* baseReturner = &returner;
现在将DummyDerived*
从DerivedReturner
和DummyBase*
从同一个返回器转换为IBaseReturner
:
DummyDerived* derivedOriginal = returner.Get();
DummyBase* baseFromInterface = baseReturner->Get();
比较就像上面一样:
std::cout << "Derived Original : " << derivedOriginal << std::endl;
std::cout << "Base from Interface : " << baseFromInterface << std::endl;
输出
Derived Original : 00000000002CF838
Base from Interface : 00000000002CF838
与上面不同,指针具有相同的值。 现在比较它们:
std::cout << "IsSame : " << (baseFromInterface == derivedOriginal) << std::endl;
输出:
IsSame : 0
即使地址相同,比较也会返回false
。 这是预期的,因为指向DummyBase
的指针应该具有不同的值。 同样在尝试 dynamic_cast 时:
std::cout << dynamic_cast<DummyDerived*>(baseFromInterface);
并抛出异常:
unknown file: error: C++ exception with description "Access violation - no RTTI data!" thrown in the test body.
显然,因为指针没有正确偏移。
似乎在调用IBaseReturner::Get
,visual-c++ 编译器无法执行必要的指针运算将DummyDerived*
为DummyBase*
。 这发生在 vs2013 和 vs2015(没有尝试任何其他版本)。 此外,当使用 gcc 编译时,它工作正常。
虽然设置可能有点复杂,但问题相当简单:
这是 msvc 错误还是我导致了未定义的行为?
添加了一个在线示例: http : //rextester.com/KHZXGQ27304
您的代码没有未定义的行为(GCC 和 Clang 都可以正常编译和执行,演示: https : //gcc.godbolt.org/z/q91vbhjTh ),并且由于 MSVC 中的错误,其运行失败,该错误仍然存在存在于 Visual Studio 2019 和 2022 中。
报告的 MSVC 错误: https : //developercommunity.visualstudio.com/t/Invalid-code-generated-for-virtual-inher/1598214
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.