2016-05-12 1 views
-1

ここではコンパイルできないコードです:のstd ::マップとプライベートコンストラクタ

#include <map> 
using namespace std; 

class A; 

class B { 
     friend class A; 
     int b; 
     B():b(1){}; 
     B(int b_):b(b_){}; 
}; 

class A { 
     map<int,B> objects; 
public: 
     void init(){ 
       objects[2]=B(3); 
     } 
}; 

int main(){ 
     A a; 
     a.init(); 
     return 0; 
} 

私は、エラーメッセージに理解し何からは:

/usr/include/c++/4.8/bits/stl_map.h: In instantiation of ‘std::map<_Key, _Tp, _Compare, _Alloc>::mapped_type& std::map<_Key, _Tp, _Compare, _Alloc>::operator[](const key_type&) [with _Key = int; _Tp = B; _Compare = std::less<int>; _Alloc = std::allocator<std::pair<const int, B> >; std::map<_Key, _Tp, _Compare, _Alloc>::mapped_type = B; std::map<_Key, _Tp, _Compare, _Alloc>::key_type = int]’: 
foo.cc:18:24: required from here 
foo.cc:9:10: error: ‘B::B()’ is private 
      B():b(1){}; 
     ^
In file included from /usr/include/c++/4.8/map:61:0, 
       from foo.cc:1: 
/usr/include/c++/4.8/bits/stl_map.h:469:59: error: within this context 
      __i = insert(__i, value_type(__k, mapped_type())); 
                 ^

問題は、「マップ」ではありませんBの友人なので、コンストラクタB()を使用しないことがあります(ちなみにobjects[2]=B(3);にはB()が必要です)。 ~B()もプライベートになるまで...働く

objects.insert(pair<int,B>(2,B(3))); 

は、私は次の回避策を見つけました。

したがって、Bのコンストラクタとデストラクタがプライベートの場合、Aの内部にBのマップを作成する方法はありますか?

その他の質問:objects[2]=B(3);はなぜB()を使用していますか?

+2

_ "

概略的には、あなたにあなたのコードを考えることができますBのコンストラクタとデストラクタが非公開のときに、B内のBのマップを構築する方法はありますか?「いいえ –

+0

」*エラーメッセージでわかったことから*「どのようなエラーメッセージが表示されますか? – user2079303

+0

なぜdownvote? –

答えて

3

厳密に言えば、それはあなたの質問に対する答えではありませんが、私はあなたの問題をより洗練された方法で解決すると思います。

代わりにB、民間のすべてのフィールドを作り、その後、Aで友人のキーワードをいじりの、あなたがプライベートmember classをそれを作ることで、外の世界からクラスBを隠すことがあります

#include <map> 

class A { 
    class B { 
     int b; 

     public: 
     B() : b(1){}; 
     B(int b_) : b(b_){}; 
     ~B() {} 
    }; 
    std::map<int, B> objects; 

    public: 
    void init() { 
     auto b = B(); 
     objects[2] = B(3); 
     objects.insert(std::pair<int, B>(2, B(3))); 
    } 
}; 

int main() { 
    A a; 
    A::B b; // 'A::B': cannot access private class declared in class 'A' 
    a.init(); 
    return 0; 
} 

この道をあなたはまだできませんBをAの外側で自由に構成することができますが、Aはそれをどのようにしても使用できます。これはまた、Bでのカプセル化のより細かい粒度を解きます:いくつかの部分はプライベート/ Aから保護されることができます。それは友人のクラスコードの場合ではありません。私のコードはもっと似ているが

A [ B [ private(a), private(b), private(c), ... ] ] 

A[ private(B[a, b, c]) ] 

すなわちprivatenessであるBの "因数分解" だから、

+0

これはまさに私が必要なものです!私はプライベートメンバークラスを知らなかった。どうもありがとう。 –

1

このリンクhttp://www.cplusplus.com/reference/map/map/operator[]/を見て、それがこの関数の呼び出しは同等です

を言う:デフォルトのコンストラクタは、クラスstd::map「内から呼び出されている

(*((this->insert(make_pair(k,mapped_type()))).first)).second 

スコープは、このクラスの友人ではありません。したがって、エラー。

エラーがあります。そのようなコンストラクタはプライベート宣言されるべきではありません。

この問題を解決するもう一つの方法は、オブジェクトの構成をクラスAに委任し、ポインタ(または参照ラッパー)からBへの整数のマップを持つことです。このマップは、インターフェイスそのAが公開されます。そうすれば、Bオブジェクトの全寿命はAで管理され、不変量は壊れません。

+1

お返事ありがとうございます。私はエラーの妥当性を議論していませんでした。理由を理解しておらず、解決策を探していませんでした。 –

+1

@ L.Levrel私はまともなと思ったソリューションを投稿しておくべきでした!私は他のものに精通していて、それについて考えなかった。私は私の答えを編集します – Curious

+1

それはまともだった。 Lispのような引用(非常に多くのカッコ)は、私がオペレータ[]が何をしているかを慎重に調べることを余儀なくさせた。それは役に立ちました。私は落ち着いた答えを受け入れましたが、質問に答えることはできませんが、厳密に言えば、私にはこれを許してください。すでにupvoted答えを編集する時間をとってくれてありがとう、私はそれを2回upvoteできないので、私はあなたのコメントをupvoteします:あなたの2,000人の担当者への小さな一歩! (彼らは、上書きされたコメントのために担当者を与えてくれる?) –

関連する問題