- ベストアンサー
C++でfriendクラスにしているのにprivateメンバにアクセスできない
C++でメンバ変数をprivateにして、特定のクラスにだけ公開するようにクラスをfriend指定したのですがprivateメンバにアクセスできませんとエラーが吐かれてしまいます。 先行宣言したりもしてみたのですがどうしても使用できません。 何か心当たりのあるかた教えてください。 class A { friend class B; private: int a; }; class B { public: void test( A *a ) { a->a = 0; } }; コードは違いますがこんな感じのことをしたいのです。 /* コンソールで小さなプログラムでテストしてみると動くのにいざ実際のソースに組み込むと動かないという奇妙な状態です。よろしくお願いします。 */
- みんなの回答 (6)
- 専門家の回答
質問者が選んだベストアンサー
こんにちは。御礼頂き有難うございます。 以下でコンパイルに通りました。 namespace NS1 { namespace NS2 { class B; } } namespace NS1 { namespace NS2 { namespace NS3 { class A { friend class NS1::NS2::B;//ココでは? private: int num; }; } } } namespace NS1 { namespace NS2 { class B { public: void test( NS3::A *a ) { a->num = 0; } }; } }
その他の回答 (5)
- rinkun
- ベストアンサー率44% (706/1571)
ANo.4へのお礼の記述からすると、friend宣言でのclass Bが、NS1::NS2::NS3::Bか::Bとみなされているのでは? friend class NS1::NS2::B; と書いてみてはどう?
お礼
回答ありがとうございます。 指摘されたとおり直してみたのですが 'B' : 'NS1::NS2' のメンバではありません。 という、エラーが出ています。
- machongola
- ベストアンサー率60% (434/720)
こんにちは。補足いただきました。 >>namespaceのせいで名前間違いが発生しているのかと思い確認してみたのですがどうも違うようです。 namespaceを使用していますか。でしたら、以下のどちらか。 ------------------------------------------------------------ クラスAのみネームスペース内にある。 class B;//此れが無いと駄目 namespace NSA { class A { friend class B; private: int a; }; };//namespace NSA class B { public: void test( NSA::A *a ) { a->a = 0; } }; ------------------------------------------------------------ クラスA、クラスBとも別のネームスペース内にある時。 namespace NSB//此れが無いと駄目 { class B; };//namespace NSB namespace NSA { class A { friend class NSB::B; private: int a; }; };//namespace NSA namespace NSB { class B { public: void test( NSA::A *a ) { a->a = 0; } }; };//namespace NSB ------------------------------------------------------------ これでも無理であるならば、私はギブアップです、すんません。
お礼
事細かに説明していただき本当にありがとうございます。 namespace NS1 { namespace NS2 { namespace NS3 { class A { friend class B; private: int num; }; } } } namespace NS1 { namespace NS2 { class B { prublic: void test( NS3::A *a ) { a->num = 0; } }; } } ネームスペースの説明も不十分でしたね・・・。 とりあえず現在こんな感じのコードを書いてしまっています。 class Aとclass Bは違うヘッダーファイル内に記述していて、class Aのほうがclass Bの1個下のネームスペースに入っている感じです。 ご指摘のようにコードを変えて試行錯誤してみたのですがやはりprivateメンバにアクセスできないようです。 本当に丁寧にありがとうございます。
- titokani
- ベストアンサー率19% (341/1726)
>コンソールで小さなプログラムでテストしてみると動くのにいざ実際のソースに組み込むと動かないという奇妙な状態です。 そういった場合は、動く場合と動かない場合とでなにが違うのかを突き止めるしか方法がないような。 #経験ありますが、単純なミスだったりするんだよなぁ・・・(^^;
お礼
そうなんですよね^^; 大概こういうエラーって自分の単純なミスなんだと思います^^; 少し離れて時間を置いてから見てみると理由がわかったりするのですが、なかなか時間が取れなくて。 どうもありがとうございます。
- machongola
- ベストアンサー率60% (434/720)
こんばんは。補足いただきました。 >>メンバ変数をpublicにするとアクセスできることからinclude抜けではないとおもうのですが。 friend class ???に指定したクラス名が間違ってはいませんでしょうか。 例えば、 class A { friend class BB;//ココ、名前が間違ってしまっている。 private://publicにすると通る int a; }; class B { public: void test( A *a ) { a->a = 0; } }; とか。又は、継承の断層で class A { friend class I; private://publicにすると通る int a; }; class I { virtual void test( A *a) = 0;//クラスBでオーバーライドする }; class B : public I { public: void test( A *a )//触ろうとする { a->a = 0; } };
補足
回答ありがとうございます。 すみません、publicでアクセスできるのは当たり前でした。今気づきました。 namespaceのせいで名前間違いが発生しているのかと思い確認してみたのですがどうも違うようです。 継承の問題でもなさそうです。
- machongola
- ベストアンサー率60% (434/720)
こんばんは。 クラスBを実装しているソースに、クラスBのヘッダーを確りとインクルードされていない可能性があります。 「'a' : privateメンバにアクセスできません」の他に「認識できない型'B'が使われています」が表示されていませんでしょうか? 再現するとすれば、以下の様な感じです。 //a.hppの中 //+----------------------------------- #ifndef __A_HPP__ #define __A_HPP__ class A { friend class B; private: int a; }; #endif //-----------------------------------+ //b.hppの中 //+----------------------------------- #ifndef __B_HPP__ #define __B_HPP__ class A; class B { public: void test( A *a ); }; #endif //-----------------------------------+ //b.cppの中 //+----------------------------------- #include"a.hpp" #include"b.hpp"//ココをコメントアウトすると再現出来る void B::test( A *a ) { a->a = 0; } //-----------------------------------+
補足
回答ありがとうございます。 確認してみたところ「認識できない型'B'が使われています」は表示されていないようです。 メンバ変数をpublicにするとアクセスできることからinclude抜けではないとおもうのですが。
お礼
回答ありがとうございます。 提示していただいたソースでやっとこさコンパイルが通ってくれました。 今回は丁寧に何度もソースを書いていただいたり、深く追求してくださったりしてありがとうございました。 重ねてお礼申し上げます。 ありがとうございました。