11
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's 一起工作,Interface(和Foo::GetInterfaces())被实现为与只应该知道Interface功能的单独模块交互。

如果这里有任何不清楚的地方,请告诉我,这对我来说很有意义,但我一直在努力解决这个问题。

4

2 回答 2

11

铸造不正确,它们是不同的类型;我很确定您正在调用未定义的行为。

您需要构造一个新向量并按值返回它。

std::vector<std::shared_ptr<Interface>> b (m_data.begin(), m_data.end());
return b;

这应该仍然相当便宜(1 个分配)。

于 2013-02-19T18:41:44.707 回答
4

除了这在 的实现中是不可能的之外vector,问题还在于引用不转换。您的代码更糟糕,并且是未定义的行为。

您可以做的是提供一个接口来公开范围或begin/end代替容器本身。如果将其与进行transform_iterator转换的 a 结合使用,则应该进行设置。

示例代码:

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());
  }
};
于 2013-02-19T18:43:33.450 回答