1

ここに私が持っているものがあります:

class A{
    B* object;
    const B& create_object(){
        if(object == nullptr)
            object = new B(this);
        return *object;
    }
}

さて、これが問題です。A 以外の方法で B を作成することを許可しないことになっています。B オブジェクトを作成できる唯一の方法は次のとおりです。

A a;
auto b1 = a.create_object();

オブジェクトの作成を許可しないことになっているので、B のコンストラクターをすべて非公開にし、A は B のフレンドであると言いました。

auto b1 = a.create_object();

コピーコンストラクターが呼び出されるとコンパイルされません。それを回避する方法はありますか?ポインターを返したくありません。オブジェクトである必要があります。

4

2 に答える 2

6

b1Bではなくと推定されるconst B&ため、コンパイラは copy-ctor が利用可能であることを確認します。const auto&この場合に使用します

A a;
const auto& b1 = a.create_object();
于 2013-11-08T13:15:31.920 に答える
0

プロキシ オブジェクトを使用して、必要なことを行うことができます。

class source_of_B
{
  class B &source;
  source_of_B(B &source): source(source) {}
  friend class A;
  friend class B;
};

パブリック コンストラクターがないため、このようなオブジェクトの作成はそのフレンドに制限されます。したがって、制御された場所に B を作成するという要件を損なうことなく、プロキシを受け入れるパブリック コンストラクターを B に追加できます。

class B
{
  int x;
  B(int x): x(x) {}
  friend class A;
public:
  B(const source_of_B &arg): x(arg.source.x) {}
};
class A
{
  B b;
public:
  A(): b(5) {}
  source_of_B create_object() { return source_of_B(b); }
};

int main()
{
  A a;
  B b = a.create_object();
}

auto b = a.create_object();しかし、この方法では使用できなくなりました。

編集

お使いのコンパイラが戻り値の最適化をサポートしている場合 (おそらくサポートしている場合)、プロキシを使用しなくてもかまいません。直接create_object()戻るように変更するだけです:B

  B create_object() { return b; }

  auto b2 = a.create_object();

コピー コンストラクターは、単独で呼び出されcreate_object()ます。唯一の問題は、一部の (古い) コンパイラには関数の複雑さに制限があることです。たとえば、ウィキペディアの記事を参照してください。実際の例はhttp://ideone.com/w1jKAdにあります。

于 2013-11-08T14:51:18.100 に答える