class Interface
{
};
class Class : public Interface
{
};
class Foo
{
public:
std::vector<std::shared_ptr<Interface>>& GetInterfaces()
{
return *(std::vector<std::shared_ptr<Interface>>*)(&m_data);
//return m_data;
}
private:
std::vector<std::shared_ptr<Class>> m_data;
};
这很有效,但很丑陋而且很可怕。 是否有更好/更安全的方法呢?我不想m_data
类型为std::vector<std::shared_ptr<Interface>>
,因为模块Foo
属于完全适用于Class
,Interface
(和Foo::GetInterfaces()
)已实现与仅应了解Interface
功能的单独模块进行交互。
让我知道这里有什么不清楚的地方,对我来说这是有意义的,但我已经对这个问题进行了一段时间的反击。
答案 0 :(得分:9)
投射不正确,它们是不同的类型;我很确定你正在调用未定义的行为。
您需要构造一个新的向量并按值返回。
std::vector<std::shared_ptr<Interface>> b (m_data.begin(), m_data.end());
return b;
这仍然相当便宜(1次分配)。
答案 1 :(得分:4)
除了vector
的实现这是不可能的,问题还在于引用不能转换。您的代码更糟糕,并且是未定义的行为。
您可以做的是提供一个公开范围或begin/end
而不是容器本身的界面。如果将其与执行转换的transform_iterator
组合使用,则应设置。
示例代码:
class Interface {
virtual ~Interface();
};
class X : public Interface {};
class C {
private:
typedef std::shared_ptr<Interface> iptr_type;
typedef std::shared_ptr<Class> ptr_type;
std::vector<ptr_type> v_;
struct F {
iptr_type
operator()(ptr_type p) { return iptr_type(p); }
};
typedef boost::transform_iterator<
F, std::vector<ptr_type>::iterator> iiterator;
public:
iiterator
begin()
{
return boost::make_transform_iterator(
begin(v_), F());
}
iiterator
end()
{
return boost::make_transform_iterator(
end(v_), F());
}
};