функция друга std :: make_shared () в Visual Studio 2010 (не Boost) - PullRequest
4 голосов
/ 23 сентября 2011

как сделать функцию друга из std::make_shared().

Я пытался:

class MyClass{
public:
     friend std::shared_ptr<MyClass> std::make_shared<MyClass>();
     //or
     //friend std::shared_ptr<MyClass> std::make_shared();
protected:
     MyClass();
};

, но она не работает (я использую Visual Studio 2010 SP1)

Ответы [ 4 ]

10 голосов
/ 23 сентября 2011

Как насчет добавления статического метода в ваш класс:

class Foo
{
public:
  static shared_ptr<Foo> create() { return std::shared_ptr<Foo>(new Foo); }
private:
  // ...
};

Вот небольшой взлом:

class Foo
{
  struct HideMe { };
  Foo() { };
public:
  explicit Foo(HideMe) { };
  static shared_ptr<Foo> create() { return std::make_shared<Foo>(HideMe());
};

Никто не может использовать открытый конструктор, кроме самого класса.По сути, это неинтерфейсная часть публичного интерфейса.Спросите людей Java, есть ли у такой вещи имя: -)

4 голосов
/ 23 сентября 2011

Это не работает, потому что реализация VC10 передает конструкцию внутренней вспомогательной функции.Вы можете покопаться в исходном коде и добавить эту функцию в друзья, если хотите.

1 голос
/ 17 мая 2013

Если у вас все в порядке с углублением во внутренние детали реализации используемого вами компилятора, для VC10 / Visual C ++ 2010, как упоминалось @DeadMG, вы можете подружиться с внутренней реализацией.Вам захочется подружиться std::tr1::_Ref_count_obj<T>.

Я проверил это с помощью оптимизирующего компилятора Microsoft (R) C / C ++ версии 16.00.40219.01 для x64

.
0 голосов
/ 23 сентября 2011

Класс, к внутренним данным которого вы хотите получить доступ, должен объявлять другие классы друзьями, поскольку это нарушает стандартную инкапсуляцию.

Невозможно, чтобы std :: make_shared сделал ваш класс другом, и, есливы не меняете std :: make_shared, он не должен хотеть, чтобы ваш класс был другом.

Так что, если я не правильно понял вопрос - то, что вы спрашиваете, не может быть сделано.

...