C++ 中的协变返回类型究竟是什么? [英] What exactly are covariant return types in C++?

查看:34
本文介绍了C++ 中的协变返回类型究竟是什么?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

A 类{虚拟 std::vectortest() {/* 做某事 */};}B类:公共A{虚拟 std::vectortest() {/* 做某事 */};}

我假设 A 和 B 是协变类型,因此 A* 和 B* 也应该是(正确的?)通过推断,我本来希望 std::vectorstd::vector 也应该是协变的,但情况似乎并非如此.为什么?

解决方案

协变返回类型允许派生类中被重写的虚成员函数返回不同类型的对象,只要它可以以相同的方式使用基类的返回类型.计算机科学家(自 Barbara Liskov 起)对可以以相同方式使用"的理论定义为:替代性.

不,std::vector 不是 std::vector 的子类型,也不应该是.>

例如std::vector不支持push_back(A*)操作,所以不可替代.

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

I get a compile error when I try to do this:

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

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

I assume that A and B are covariant types, and hence A* and B* should also be (Correct?) By inference, I would have expected that std::vector<A*> and std::vector<B*> should be covariant as well, but this does not seem to be the case. Why?

解决方案

Covariant return types allow overridden virtual member functions in a derived class to return a different type of object, as long as it can be used in all the same ways as the base class's return type. Computer scientists have (ever since Barbara Liskov) a theoretical definition of "can be used in the same ways": substitutability.

No, std::vector<B*> is not a subtype of std::vector<A*>, nor should it be.

For example, std::vector<B*> doesn't support the push_back(A*) operation, so it is not substitutable.

C++ doesn't try to infer subtype relationships for templates at all. The relationship will only exist if you actually specialize one and specify a base class. One reason for this, even on interfaces which are theoretically covariant (basically, read-only), is that C++'s version is actually stronger than Liskov substitution -- in C++ the compatibility has to exist at a binary level. Since the memory layout of collections of related objects may not match subobject placement, this binary compatibility isn't achieved. The restriction of covariant return types to be only pointers or references is also a consequence of the binary compatibility issue. A derived object probably wouldn't fit in the space reserved for the base instance... but its pointer will.

这篇关于C++ 中的协变返回类型究竟是什么?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆