C++ 中的协变返回类型到底是什么?

2023-12-13

当我尝试执行此操作时出现编译错误:

class A
{
    virtual std::vector<A*> test() { /* do something */ };
}

class B: public A
{
    virtual std::vector<B*> test() { /* do something */ };
}

我假设 A 和 B 是协变类型,因此 A* 和 B* 也应该是(正确吗?)通过推断,我预计std::vector<A*> and std::vector<B*>也应该是协变的,但情况似乎并非如此。为什么?


协变返回类型允许派生类中重写的虚拟成员函数返回不同类型的对象,只要它可以按照与基类的返回类型相同的方式使用即可。计算机科学家(自 Barbara Liskov 以来)对“可以以相同的方式使用”有一个理论定义:可替代性.

No, std::vector<B*>不是 的子类型std::vector<A*>,也不应该是这样。

例如,std::vector<B*>不支持push_back(A*)操作,因此不可替代。

C++ 根本不尝试推断模板的子类型关系。仅当您实际专门化一种关系并指定基类时,这种关系才会存在。其原因之一是,即使在理论上协变(基本上是只读)的接口上,C++ 的版本实际上比里氏替换更强——在 C++ 中,兼容性必须存在于二进制级别。由于相关对象集合的内存布局可能与子对象放置不匹配,因此无法实现这种二进制兼容性。协变返回类型仅限于指针或引用也是二进制兼容性问题的结果。派生对象可能不适合为基本实例保留的空间......但它的指针可以。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

C++ 中的协变返回类型到底是什么? 的相关文章

随机推荐