如何在仅具有受保护或私有构造函数的类上调用:: std :: make_shared?

万能的

我的这段代码行不通,但是我认为目的很明确:

testmakeshared.cpp

#include <memory>

class A {
 public:
   static ::std::shared_ptr<A> create() {
      return ::std::make_shared<A>();
   }

 protected:
   A() {}
   A(const A &) = delete;
   const A &operator =(const A &) = delete;
};

::std::shared_ptr<A> foo()
{
   return A::create();
}

但是在编译时会出现以下错误:

g++ -std=c++0x -march=native -mtune=native -O3 -Wall testmakeshared.cpp
In file included from /usr/lib/gcc/x86_64-redhat-linux/4.6.1/../../../../include/c++/4.6.1/bits/shared_ptr.h:52:0,
                 from /usr/lib/gcc/x86_64-redhat-linux/4.6.1/../../../../include/c++/4.6.1/memory:86,
                 from testmakeshared.cpp:1:
testmakeshared.cpp: In constructor ‘std::_Sp_counted_ptr_inplace<_Tp, _Alloc, _Lp>::_Sp_counted_ptr_inplace(_Alloc) [with _Tp = A, _Alloc = std::allocator<A>, __gnu_cxx::_Lock_policy _Lp = (__gnu_cxx::_Lock_policy)2u]’:
/usr/lib/gcc/x86_64-redhat-linux/4.6.1/../../../../include/c++/4.6.1/bits/shared_ptr_base.h:518:8:   instantiated from ‘std::__shared_count<_Lp>::__shared_count(std::_Sp_make_shared_tag, _Tp*, const _Alloc&, _Args&& ...) [with _Tp = A, _Alloc = std::allocator<A>, _Args = {}, __gnu_cxx::_Lock_policy _Lp = (__gnu_cxx::_Lock_policy)2u]’
/usr/lib/gcc/x86_64-redhat-linux/4.6.1/../../../../include/c++/4.6.1/bits/shared_ptr_base.h:986:35:   instantiated from ‘std::__shared_ptr<_Tp, _Lp>::__shared_ptr(std::_Sp_make_shared_tag, const _Alloc&, _Args&& ...) [with _Alloc = std::allocator<A>, _Args = {}, _Tp = A, __gnu_cxx::_Lock_policy _Lp = (__gnu_cxx::_Lock_policy)2u]’
/usr/lib/gcc/x86_64-redhat-linux/4.6.1/../../../../include/c++/4.6.1/bits/shared_ptr.h:313:64:   instantiated from ‘std::shared_ptr<_Tp>::shared_ptr(std::_Sp_make_shared_tag, const _Alloc&, _Args&& ...) [with _Alloc = std::allocator<A>, _Args = {}, _Tp = A]’
/usr/lib/gcc/x86_64-redhat-linux/4.6.1/../../../../include/c++/4.6.1/bits/shared_ptr.h:531:39:   instantiated from ‘std::shared_ptr<_Tp> std::allocate_shared(const _Alloc&, _Args&& ...) [with _Tp = A, _Alloc = std::allocator<A>, _Args = {}]’
/usr/lib/gcc/x86_64-redhat-linux/4.6.1/../../../../include/c++/4.6.1/bits/shared_ptr.h:547:42:   instantiated from ‘std::shared_ptr<_Tp1> std::make_shared(_Args&& ...) [with _Tp = A, _Args = {}]’
testmakeshared.cpp:6:40:   instantiated from here
testmakeshared.cpp:10:8: error: ‘A::A()’ is protected
/usr/lib/gcc/x86_64-redhat-linux/4.6.1/../../../../include/c++/4.6.1/bits/shared_ptr_base.h:400:2: error: within this context

Compilation exited abnormally with code 1 at Tue Nov 15 07:32:58

该消息基本上是说,从模板实例化堆栈中向下移动的某种随机方法::std::make_shared无法访问构造函数,因为它是受保护的。

但是我真的很想同时使用这两种方法,::std::make_shared并防止任何人制作此类未由a指向的对象::std::shared_ptr有什么办法可以做到这一点?

万能的

这个答案可能更好,我可能会接受。但是我也想出了一个比较丑陋的方法,但是它仍然让所有内容都内联并且不需要派生类:

#include <memory>
#include <string>

class A {
 protected:
   struct this_is_private;

 public:
   explicit A(const this_is_private &) {}
   A(const this_is_private &, ::std::string, int) {}

   template <typename... T>
   static ::std::shared_ptr<A> create(T &&...args) {
      return ::std::make_shared<A>(this_is_private{0},
                                   ::std::forward<T>(args)...);
   }

 protected:
   struct this_is_private {
       explicit this_is_private(int) {}
   };

   A(const A &) = delete;
   const A &operator =(const A &) = delete;
};

::std::shared_ptr<A> foo()
{
   return A::create();
}

::std::shared_ptr<A> bar()
{
   return A::create("George", 5);
}

::std::shared_ptr<A> errors()
{
   ::std::shared_ptr<A> retval;

   // Each of these assignments to retval properly generates errors.
   retval = A::create("George");
   retval = new A(A::this_is_private{0});
   return ::std::move(retval);
}

编辑2017年1月6日:我对此进行了更改,以明确地表明此思想对于带有参数的构造函数很容易扩展,因为其他人正在按照这些思路提供答案,并且对此感到困惑。

本文收集自互联网,转载请注明来源。

如有侵权,请联系 [email protected] 删除。

编辑于
0

我来说两句

0 条评论
登录 后参与评论

相关文章

函数std :: make_shared <vector>的参数过多

如何避免使用std :: make_shared分配大内存

如何阻止使用std :: make_shared <T>

如何理解`std::make_shared<Object>("foo")`?

我如何理解 std::make_shared 的工作原理?

带有std :: make_shared的密码成语。xmemory无法访问私钥构造函数

std :: make_shared和std :: make_unique在幕后如何工作?

共享指针仅通过std :: shared_ptr初始化。std :: make_shared构造函数不起作用

boost :: make_shared失败,但std :: make_shared工作

带有std :: make_shared的std :: weak_ptr分配

std :: apply内部的std :: make_shared

如何使用std :: make_shared创建基类类型的智能指针?

有什么办法可以欺骗std :: make_shared使用默认初始化吗?

带有dtor和libc ++的std :: make_shared无法编译

我可以将std :: make_shared与没有参数构造函数的结构一起使用吗?

是否可以强制`std :: make_shared`使用类的新运算符?

为什么不能使用std :: make_shared的实例化作为函数的指针?

C ++ std :: make_shared与新的宏

std :: make_shared内部的原始指针

C++ std::make_shared

std::make_shared 值是否初始化其默认构造函数未初始化的类成员?

私有构造函数和make_shared

在 C++ 中使用 std::make_shared 的“类型擦除”代码中的类和结构有什么区别?

如何make_shared派生类?

考虑到智能指针以及函数std :: make_shared和std :: make_unique,关键字new及其对应的delete是否已过时?

使用 make_shared 防止复制构造

如何使用`make_shared`创建指针

std :: make_shared三元返回不编译

std :: make_shared给出我不明白的错误