【发布时间】:2009-11-16 11:52:37
【问题描述】:
考虑以下示例代码:
class Foo
{
};
class Bar : public Foo
{
};
class FooCollection
{
protected:
vector<shared_ptr<Foo> > d_foos;
};
class BarCollection : public FooCollection
{
public:
vector<shared_ptr<Bar> > &getBars()
{
// return d_foos won't do here...
}
};
我在当前的项目中遇到了这样的问题。客户端代码使用BarCollection,它将指向Bars 的指针存储在d_foos 中,FooCollection 中声明。我现在想将指向 Bars 的指针集合公开给客户端代码。我可以让客户端代码访问指向Foos 的指针向量,并将它们转换为客户端代码中指向Bars 的指针,但这感觉不对,因为客户端不必知道Foo的存在。
我还可以定义一个get() 成员,它从d_foos 检索对象并强制转换它们,但这感觉很笨拙。最好将 d_foos 作为vector<shared_ptr<Bar> > & 返回,但我似乎无法做到这一点。
也可能是我的设计完全错误。不过,这似乎是最自然的解决方案,因为 Bar 是 Foo 的特化,BarCollection 是 FooCollection 的特化,它们共享功能。
您能否建议在BarCollection 中实现getBars 或更好的设计替代方案的好解决方案?
编辑:
事实证明我的设计确实很糟糕。 BarCollection 不是 FooCollection,尽管它需要 FooCollection 的所有功能。我目前基于以下答案的解决方案——更简洁——现在是:
class Foo
{
};
class Bar : public Foo
{
};
template<class T>
class Collection
{
vector<shared_ptr<T> > d_items;
};
typedef Collection<Foo> FooCollection;
class BarCollection : public Collection<Bar>
{
// Additional stuff here.
};
感谢所有优秀的建议和示例!
【问题讨论】:
-
我已经发布了一个解决方案……主要是为了完整性,因为它涉及
reinterpret_cast。我强烈敦促您考虑重构替代方案。特别是,您将继承引入的IS-A关系与代码重用混为一谈。此外,您不想在那里有getBars。暴露你的私处被认为是暴露狂,会受到法律的惩罚。 -
@Matthieu:我已经为这个问题添加了我重构的当前解决方案。谢谢!
标签: c++ vector polymorphism shared-ptr