Как полностью скрыть определенный тип, используя typedef? - PullRequest
1 голос
/ 10 марта 2010

У меня быстрый вопрос об инкапсуляции определенных типов с typedef. Скажем, у меня есть класс Foo, конструктор которого принимает определенное значение, но я хочу скрыть определенный тип, используя typedef:

class Foo {
public:
  typedef boost::shared_ptr< std::vector<int> > value_type;  
  Foo(value_type val) : val_(val) {}
private:
  value_type val_;
};

Но в этом случае основная функция все еще должна знать тип (поэтому она явно использует std::vector<int>):

int main() {
  Foo::value_type val(new std::vector<int>());
  val->push_back(123);
  Foo foo(val);
  return 0;
}

Как я могу это исправить, избегая глубокой копии вектора в конструкторе Foo?

Ответы [ 2 ]

6 голосов
/ 10 марта 2010

Различные решения:

Foo::value_type val(new Foo::value_type::element_type());
// least change from your current code, might be too verbose or too
// coupled to boost's smart pointer library, depending on your needs

Foo::value_type val(new Foo::element_type());
// add this typedef to Foo: typedef value_type::element_type element_type;

Foo::value_type val = Foo::new_value_type();
// static method in Foo, allows you to even easily change from new (as you
// encapsulate the whole smart pointer, and can specify another deleter to the
// boost::shared_ptr)

struct Foo {
  static value_type new_value_type() { // function used above
    return value_type(new value_type::element_type());
  }
};

Однако, если все, что вам нужно, это инициализировать элемент вектора в Foo извне данных, не копируя его, вместо того, чтобы фактически делиться через shared_ptr, тогда я бы вообще не использовал shared_ptr. Возьмите ссылку в ctor'е Фу и документально подтвердите, что он меняет объект.

struct Foo {
  typedef std::vector<int> value_type;
  explicit Foo(value_type& val) {
    using std::swap;
    swap(val, _val);
  }

private:
  value_type _val;
};

int main() {
  Foo::value_type val;
  val->push_back(123);
  Foo foo(val);
  return 0;
}
1 голос
/ 10 марта 2010

В приведенном примере нет глубокой копии. Shared_ptr копируется, но создается только один вектор. Вы можете подтвердить это, вызвав push_back второй раз после конструктора Foo и заметив, что Foo.val_ также изменяется.

...