1

クラスのプライベートコンストラクターに到達できるようにするために、クラスと友達になろうとしています。

some_file.h で

class B;    

namespace some_name {
class A {
  public:
    A() {}
  private:
    A (int x) {}
    friend class ::B;
};
}

other_file.h 内

#include "some_file"

namespace {
class B {
  protected:
    A* get_a(int x) { return new A(x); }
};   
}

このコードをコンパイルすると、エラーが発生します: 'some_name::A::A(int)' is private.

私は今、非公開です。これが私が B と友達になった理由です。ここで何が間違っているのでしょうか? コンストラクターと友達になりませんか?名前空間の問題はありますか?

ありがとう

4

4 に答える 4

9

これを行う:

namespace {
class B {
  protected:
    A* get_a(int x) { return new A(x) };
}   
}

Bルート (グローバル) 名前空間ではなく、匿名の名前空間に入れています。

そのため、 ではB到達できません::B

ルート (グローバル) 名前空間に入れたい場合はB、まったく囲まないでくださいnamespace。これでうまくいくはずです。

于 2010-08-25T14:55:29.440 に答える
1

グローバル名前空間でクラス B を前方宣言してフレンド登録しただけです。名前空間のクラス B ではありません。B の名前を完全修飾する必要があります。

編集: ereOn に感謝します。
少しミスをしました。あなたが問題を抱えているのは、あなたが B を誤って宣言し、誤って参照したためであることは事実ですが、私の元の声明はまったく真実ではありませんでした。匿名の名前空間から B を取り出す必要があります - とにかくヘッダーにいるのは無意味です。

于 2010-08-25T14:55:53.833 に答える
0

問題は、代わりにBasを参照することです。つまり、グローバル名であるとコンパイラに伝えていますが、実際にはそうではありません。匿名の名前空間内にあります。匿名の名前空間を削除する必要はありません。それは、期待どおりに動作しない可能性があるということだけです。匿名の名前空間はヘッダーにあるため、その名前空間の内容は、ヘッダーを含む実装ファイルに静的にリンクされます。あなたは何も隠していないので、それはあまり役に立ちません。その匿名の名前空間を削除することもできます。::BBB

于 2010-08-25T15:09:26.027 に答える
0

コンストラクターと友達になりませんか?

以下のようにできます

struct B{
    B();
    void f();
};

struct A{
    friend B::B();
private:
    A(){}
};

B::B(){A a;}       // fine

void B::f(){A a;}  // error

int main(){
}
于 2010-08-25T15:14:07.863 に答える