Covariant return type
在阅读fluentcpp Polymorphic clones in modern C++这篇文章的时候,其中提及了
Notice that the return type of the
clone
method differ between the interface in the implementation. It is because C++ allows overriding a virtual method with one that has a different return type, provided this return type is a pointer (resp. reference) to a class convertible to the one pointed to (resp. referenced by) the return type of the base class. This is called covariance.
cppreference virtual function specifier # Covariant return types
More C++ Idioms Covariant Return Types
lwithers HOWTO: Covariant Return Types in C++
class Base {
public:
virtual Base* clone() const
{
return new Base(this);
}
};
class Derived : public Base {
public:
virtual Base* clone() const
{
return new Derived(this);
}
};
However, now consider a bit of code that knows it specifically has a Derived
instance, and wishes to clone it. This code must retrieve a base class pointer and then dynamically upcast it(转换为Derived
instance). We could assume that the upcast always succeeds and not perform check, but this is bad practice (what if somebody changes the underlying function, or somebody copies and pastes the dynamic cast line?).
This leads to the following code:
Derived* d = new Derived;
Base* b = d->clone();
Derived* d2 = dynamic_cast<Derived*>(b);
if(!d2) {
delete b;
throw SomeCrazyException();
}
As you can see, this is pretty long-winded given that we know d2
should be a Derived
instance.
Fortunately, a language feature does exist to do this: covariant return types. If a derived class method returns a more-derived type than its overridden base class method, the derived class return type is said to be covariant.
class Base {
public:
virtual Base* clone() const
{
return new Base(this);
}
};
class Derived : public Base {
public:
virtual Derived* clone() const
{
return new Derived(this);
}
}
Of course, the return type does not have to be connected with the class in which the method resides. A perhaps illuminating example:
/* Inheritance hierarchies
NetServer
|
^
/ \
NetServerTCP NetServerSCTP
NetClient
|
^
/ \
NetClientTCP NetClientSCTP
*/
class NetServer {
public:
virtual NetClient* acceptConnection() = 0;
};
class NetServerTCP : public NetServer {
public:
virtual NetClientTCP* acceptConnection();
};
class NetServerSCTP : public NetServer {
public:
virtual NetClientSCTP* acceptConnection();
};
stackoverflow When is C++ covariance the best solution?
NOTE: 讨论的是,何时使用covariance
quuxplusone Covariance and contravariance in C++
这篇文章非常好
Summary of C++ covariance
一、相比于C#
的covariance,C++的covariance是比较弱的、受限的,它的使用有如下限制:
1、pointer to polymorphic type
2、virtual function
3、只能怪是return type
因此:
1、C++ 原生并不支持smart pointer的covariant return type,programmer如果想实现covariant return smart pointer,需要进行特殊的实现,参见 Guideline-covariance
章节
2、C++原生并不支持 Covariant function parameter,关于此,参见
a、sonarsource Assignment operators should not be "virtual"
TO READ
https://arne-mertz.de/2019/10/multiple-dispatch-over-covariant-functions/