- ベストアンサー
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; } }; コードは違いますがこんな感じのことをしたいのです。 /* コンソールで小さなプログラムでテストしてみると動くのにいざ実際のソースに組み込むと動かないという奇妙な状態です。よろしくお願いします。 */
- 0xEF
- お礼率59% (193/327)
- C・C++・C#
- 回答数6
- ありがとう数4
- みんなの回答 (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抜けではないとおもうのですが。
関連するQ&A
- フレンドクラスにできない
mediatorクラスからCOuterクラスのメンバ変数にアクセスできるようにフレンドクラスにしたつもりなんですが、 うまくアクセスができずコンパイルエラーになってしまいます。 どこが悪いのか分からず困っています。 どなたか助けていただけませんか? mediator.h ----------------------------------------------------- template <class T> class mediator { public: mediator(T* p=NULL) : m_p(p) {} void SetOutClass(T*p) { m_p = pT;} T& GetOutClass() const { return *m_p;} private: T* m_p; }; #define outer GetOutClass() ----------------------------------------------------- COuter.h ----------------------------------------------------- class COuter { private: int m_a; public: void func() { class CInner : public mediator<COuter> { public: CInner(COuter *p) : mediator<COuter>(p) {} void func() { // フレンドクラスなのにアクセスできない!? outer.m_a = 1; } }; CInner inner(this); inner.func(); } friend class mediator<COuter>; }; -----------------------------------------------------
- 締切済み
- C・C++・C#
- C++ のクラスの定義
C++の初心者です。 C++のことでお聞きしたいことがあります。 namespace test1{ class A { friend class B; protected: int a; }; } とtest1の下にAクラスを作り namespace test2{ class B { public: test1::A A1; }; } と別のnamespaceにBというクラスを作り、 A1というAのインスタンスを持ちたいのです。 しかし、Aというクラスを先に宣言しているので Bというクラスが解らないらしく friendがうまく働きません。 friend class test2::B としても test2がまだ宣言されていないので、 ????とコンパイルエラーが出ます。 先にtest2::B を宣言してしまうと、 今度はtest1::Aが解らずに エラーが出てしまいます。 こんな場合はどのように書けばよろしいのでしょうか? 環境はwindows2000でVC++ 6.0です。 どうか宜しくお願いいたします。
- ベストアンサー
- C・C++・C#
- クラスがメンバーとしてクラスを持つ時の宣言について
自作クラスMainClassがMyClassというクラスをメンバー変数として持つ場合、宣言時に引数をいくつか持つコンストラクタを呼び出そうとすると構文エラーとなります。 class MyClass { public: MyClass(int, int); } class MainClass { private: MyClass myclass(10,10); } このような宣言はできないのでしょうか。 引数なしのコンストラクタは呼び出せているようです。
- ベストアンサー
- C・C++・C#
- C++ 静的クラスの役割が分からない
こんばんは。 C++で静的オブジェクトがなんなのか試しにプログラミングしているんですが どんな役割があるのか試してもよく分かりません。 static class HOGE { public: int *hoge; private: int value[2]; char moji[6]; public: HOGE() { cout << "HOGE\n"; } void MOJI() { strcpy(moji, "MOJI\n"); } void TEST() { cout << "moji = " << moji << endl; } static void staticMOJI() { } }sObj; sObjからは静的メンバ関数と静的メンバ変数は呼び出せるようです。他は呼び出せません。 そのようにするためにstatic宣言をするものなのでしょうか? このsObjからメンバ変数(*hoge)を呼び出すことは無理なんでしょうか?
- ベストアンサー
- C・C++・C#
- C++ の フレンドクラスについての疑問
vc++でプログラムを作っています。 クラスのアクセス制限の部分で疑問が出てきたので、ソースとその疑問について 下記に示しています。 const int CAMERA_NUMBER = 0 class CalculateMatrix{ public: □static bool computeFundamentalMatrix( const cv::Mat P1 , const cv::Mat P2 , const cv::Mat T1 , const cv::Mat T2 , cv::Mat &F ); }; class ReferenceCameras{ □friend class CalculateMatrix; public: □ReferenceCameras(); □void setP(); □void setC(); □void setSilhouette(); private: □cv::Mat ShilhouetteImage; □int index; □cv::Mat P; □cv::Mat C; □cv::Mat F; }; void main(){ □ReferenceCameras camera0; //この宣言でプライベートメンバのF以外に全て値が入ります □ReferenceCameras camera1; // 〃 □CalculateMatrix::computeFundamentalMatrix( cameras0.P, cameras1.P , cameras0.C , cameras1.C , cameras1.F ); } という感じで ReferenceCameras型の camera0,camera1を作って そのCalculateMatrix::computeFundamentalMatrixの計算を行い。 camera1のFを計算する。 というのをやりたいのですが、main内のCalculateMatrix:FundamentalMatrixに引数を入れる部分でエラーが出ていてprivateメンバにアクセスできませんと出ます。 普通なら private で宣言しているので、そういうエラーが出るのは当然かと思いますが、 フレンドクラスの設定をしているのに、このエラーが出るのが理解できません。 結構調べたんですが、フレンドクラス、フレンド関数の部分と静的関数、ユーティリティ関数について絡めて解説しているのはなかったので詰まっています。 どうかみなさんの力を貸してください。 p.s. 何をやりたいのかわからん。や、定義書いてないやん。などの誹謗中傷はおやめください。心が傷つきます。
- ベストアンサー
- C・C++・C#
- C++ クラスをメンバにもつクラスについて
お世話になります。C++初心者でうまくコードが書けません(><) クラス1と2があり、クラス1のメンバにはクラス2があります。 メインでクラス1をインスタンス化してクラス2のfunc2を呼び出します。 func2ではクラス1のインスタンスから呼び出された場合にクラス1の m_int1を取得します。 Class Class1{ public: int m_int1; Class2 m_Class2; }; Class Class2{ public: void func2(); }; void Class2::func2(){ /*ここの記述方法が分かりません*/ /*C1から呼び出されたらC1のm_int1に100を入れる*/ /*以下間違え*/ class1 C2_1;/*別のclass1のオブジェクトなのでこれに入れてもダメっぽい*/ C2_1.m_int1 = 100; } void main(){ class1 C1; C1.m_int1 = 10; C1.m_class2.func(); } C1.m_class2.func()の中から呼び出したC1にアクセスする方法が 分かりません(TT)。実体がまだあるのだからアクセスする方法は あると思うのですが・・・ どなたかよろしくお願いします。
- ベストアンサー
- C・C++・C#
- クラスの設計の問題
今C++でクラスの設計をしています。 どう設計すれば、いいか分からないので、しっている方に教えていただきたいですが。 class A{ private: int id; public: int getId(); void setId(); }; class B{ private: int id; public: int getId(); void setId(); } class C{ private: int id; public: int getId(); void setId(); } この三つのクラスが、共通な機能があります。また、実装も同じで、 継承を利用して、どう設計すれば、いいですか? よろしくお願いします。
- ベストアンサー
- C・C++・C#
- C++ クラス概念
以下の違いがよく理解できていません。 どなたかご教授お願い致します。 (1)クラスのメンバー変数に static を付けた場合と、 メンバーではない変数に static を付けた場合の違い (2)クラスのメンバー関数に static を付けた場合と、 メンバーではない関数に static を付けた場合の違い [プログラム例] class MyClass { public: static int internalCount; static void func(MyClass& a) {/* ... */} }; static int i; static void f(MyClass& a) { /* ... */ }
- ベストアンサー
- C・C++・C#
- C++の話です。
C++の話です。 静的メンバ変数としてクラスを宣言した場合、デストラクタが呼ばれていないようなのですが、呼ぶ方法はありませんか? できれば「new」「delete」を使わずできると理想的です。 分かる方教えていただけると助かります。 以下、サンプルコードです。 「デストラクタが呼ばれました」と出力されない上、デバッガを使って試してみましたが、やはり呼ばれていないようです。 #include<iostream> class Test{ public: ~Test(){ std::cout<<"デストラクタが呼ばれました"<<std::endl; } }; class A{ private: static Test T; }; int main(){ A a; return 0; }
- ベストアンサー
- C・C++・C#
- 基本クラスと派生クラスの宣言順序
C++のクラスの宣言は、基本クラスから先に宣言しないといけないのでしょうか。 例. 次の順で宣言するとエラーになる。 class A : public B { public: private: } calss B { public: private: }
- ベストアンサー
- C・C++・C#
お礼
回答ありがとうございます。 提示していただいたソースでやっとこさコンパイルが通ってくれました。 今回は丁寧に何度もソースを書いていただいたり、深く追求してくださったりしてありがとうございました。 重ねてお礼申し上げます。 ありがとうございました。