考虑 c++98 源代码(godbolt)中的这个(简化的)类层次结构:
class Shape
{
public:
virtual class CurvilinearShape as_curvilinear_shape() const =0;
};
class CurvilinearShape : public Shape
{
// ...
public:
virtual CurvilinearShape as_curvilinear_shape() const
{
return *this;
}
};
class PolygonShape : public Shape
{
// ...
public:
virtual CurvilinearShape as_curvilinear_shape() const
{
CurvilinearShape curv_shape;
// Convert...
return curv_shape;
}
};
APolygonShape
可以轻松转换为CurvilinearShape
。 导致这两个不同类别的原因是, aPolygonShape
具有简化的描述,可以由较简单的机器处理,而更先进的机器可以处理更通用的CurvilinearShape
描述符:
void work_curvilinear_shape(CurvilinearShape const&);
在这种情况下,处理基础项序列非常方便,Shape
而不必担心实际使用的描述符,虚拟成员函数as_curvilinear_shape()
就是为此引入的:
#include <vector>
int main()
{
std::vector<Shape*> shapes;
for(std::vector<Shape*>::const_iterator it=shapes.begin(); it!=shapes.end(); ++it)
{
work_curvilinear_shape( (*it)->as_curvilinear_shape() );
}
}
CurvilinearShape::as_curvilinear_shape()
这是可行的,但是存在每次调用时(顺便说一下,大多数时候)都会发生不必要的复制构造的问题。
虽然这似乎是一个相当常见的用例,但我找不到它的名字,你知道吗?我正在寻找一种更好的方法,避免在项目已经是实例的情况下进行不必要的复制CurvilinearShape
,也许你们中的一个可以让我走上正确的轨道?
一个(有点麻烦的)解决方案是给出
as_curvilinear_shape
以下签名:如果已经是正确的形状,则返回
*this
并保持storage
不变。如果需要转换,则将转换结果赋给storage
并返回对 的引用storage
。或者您可能想要创建一个辅助类并返回它: