我最近不得不处理C++ 协方差返回类型,例如以下构造:
struct Base
{
virtual ~Base();
};
struct Derived : public Base {};
struct AbstractFactory
{
virtual Base *create() = 0;
virtual ~AbstractFactory();
};
struct ConcreteFactory : public AbstractFactory
{
virtual Derived *create()
{
return new Derived;
}
};
Run Code Online (Sandbox Code Playgroud)
它允许客户端代码在需要时将Derived对象视为Base类型或Derived类型,特别是不使用dynamic_cast或static_cast.
这种方法的缺点是什么?这是糟糕设计的标志吗?
谢谢.
协方差不适用于智能指针,因此协方差违反:
切勿通过 C++核心指南的原始指针(T*)或引用(T&)转移所有权 .有一些技巧可以限制问题,但协变值仍然是一个原始指针.
该文件的一个例子:
X* compute(args) // don't
{
X* res = new X{};
// ...
return res;
}
Run Code Online (Sandbox Code Playgroud)
这与问题中的代码几乎相同:
virtual Derived *create()
{
return new Derived;
}
Run Code Online (Sandbox Code Playgroud)
不幸的是,以下内容对于以下内容都是非法shared_ptr的unique_ptr:
struct AbstractFactory
{
virtual std::shared_ptr<Base> create() = 0;
};
struct ConcreteFactory : public AbstractFactory
{
/*
<source>:16:38: error: invalid covariant return type for 'virtual std::shared_ptr<Derived> ConcreteFactory::create()'
*/
virtual std::shared_ptr<Derived> create()
{
return std::make_shared<Derived>();
}
};
Run Code Online (Sandbox Code Playgroud)
nm的答案显示了一种模拟语言协方差的技术,以及一些额外的代码.它有一些潜在的维护成本,因此在决定走哪条路之前要考虑到这一点.