我有这段代码不起作用,但我认为意图很明确:
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
但我真的很想同时使用这两种方法::std::make_shared,并防止任何人制作一个没有被 a 指向的此类的对象::std::shared_ptr。有没有办法做到这一点?
::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-01-06: 我对此进行了更改,以表明这个想法可以清楚而简单地扩展到接受参数的构造函数,因为其他人正在按照这些思路提供答案并且似乎对此感到困惑。