私は関数の(私に言わせてください)コーナーケースに苦労しており、(std::make_shared
それほど深刻ではない)問題に対する実行可能な代替手段を見つけることができませんでした。
次のコードは正常にコンパイルされます。
#include <memory>
class A {
A() = default;
A(const A &) = default;
A(A &&) = default;
A& operator=(const A &) = default;
A& operator=(A &&) = default;
public:
static std::shared_ptr<A> create() {
// std::shared_ptr<A> ptr = std::make_shared<A>();
std::shared_ptr<A> ptr{new A};
return ptr;
}
};
int main() {
auto ptr = A::create();
}
これは直感的には、 Aという名前のユーザー定義クラスの一種のファクトリの小さな例です。
のドキュメントを見るとstd::make_shared
、次のことがわかります。
この関数は通常、new の呼び出しによって返される生のポインターから共有ポインターの構築 std::shared_ptr(new T(args...)) を置き換えるために使用されます。その式とは対照的に、std::make_shared は通常、T オブジェクトと std::shared_ptr の制御ブロックに単一のメモリ割り当てでメモリを割り当てます (これは標準では拘束力のない要件です)。 new T(args...)) は、少なくとも 2 つのメモリ割り当てを実行します。
非常に興味深いことに、コメント行を直後の行に切り替えると役立つかもしれません。関数の次のコードになりますcreate
。
static std::shared_ptr<A> create() {
std::shared_ptr<A> ptr = std::make_shared<A>();
// std::shared_ptr<A> ptr{new A};
return ptr;
}
残念ながら、このバージョンは、のプライベート コンストラクターが原因でコンパイルされませんA
(エラーは のようなものですerror: ‘constexpr A::A()’ is private
)。
明確にするために、問題はそれ自体のエラーではありません。何が原因であるかは私には明らかであり、それは理にかなっています。std::make_shared
とにかく、関数を使用し、コンストラクターを同時にプライベートにするための回避策があるかどうかを知りたいです。私が見る限り、最初の例のコードは、用語やパフォーマンスに関してよく知られた (そして文書化された) 欠点があることは言うまでもありませんが、利用可能な唯一の解決策のようです。