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>>FooClassInterfaceFoo::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設定する必要があります。

サンプルコード:

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 に答える