protected と friend はともに情報隠蔽の「抜け道」であるが、両方は大な違いがあるんですけど、それは何ですか?
ぜひ、お願いします。

A 回答 (2件)

「情報隠蔽の抜け道」って表現がどうかなあ、とは思いますが、きっと、


こういう答えを期待しているのかな?

friend は、自分の中身をさらけ出す相手を指定します。それに対して、
protected は、さらけ出す相手は自分から派生させたクラスなので、誰が
自分の中身を見るのかを特定できません。

但し、friend は、相手を特定できる代わりに、自分の中身を全てさらけ出し
ます。対して、protected は、メンバーのひとつひとつに指定ができるので
さらけ出す情報と、そうじゃないものを区別できます。

喩えると、friend は、特定の人に「鍵」を渡す(その当人にしか使えない)ような
もので、protected は、家計簿だけを鍵の掛かっていない郵便受けに入れて
置くようなものでしょうか。


なんか、C++ 自体を良く分かっていないみたいなので、この回答で意味が通じるか
自信はありません (^^;

# 根本的に意味が違う friend と protected を並べて論じるのが、ちょっと…
    • good
    • 0
この回答へのお礼

a-kuma さん:
とても、いい答えを頂きました、ありがとうございます。
また、宜しく、お願いします。
             gakuse より

お礼日時:2001/07/13 14:37

protectedはそのクラスの子孫のクラスからのアクセスを許しますが、friendはクラスの系譜を越えて指定のクラスやその中の特定の関数からのアクセスを可能にします。


また、friendは特定の関数(メンバー関数ではない)からのアクセスも可能にします。
    • good
    • 0
この回答へのお礼

natural さん:
とても、いい答えを頂きました、ありがとうございます。
また、宜しく、お願いします。
             gakuse より

お礼日時:2001/07/13 14:36

お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!

このQ&Aと関連する良く見られている質問

QC++ protectedにアクセス不可

C++でお聞きしたいことがあります。
初心者ですのでご容赦ください。

//基本クラス
class a1
{
protected:
a1();
};

//派生クラス
class a2 :public a1
{
protected:
a2():a1(){};//継承先以外から作成されたくない
int t;
};

class a3 : public a2 //a2を継承
{
public:
a3();
~a3();
private:
a2*a;//a2のポインタを持つ
};

a3::a3()
{
t = 3;
a = new a2;//コンストラクタの中でnew
}

a3::~a3()
{
delete a;//終わったらdelete
}

int main(void)
{
a3a;

return 0;
}

というソースでa3はa2を継承しています。
ですのでa2のprotectedメンバtにアクセスできるはず。
ここまではいいのですが、
a2のコンストラクタもa3でアクセスでき無いのでしょうか?
a3のコンストラクタでnewしようとすると

error C2248: 'a2::a2' : protected メンバ (クラス 'a2' で宣言されている)にアクセスできません。
a2::a2' の宣言を確認してください。

というエラーが発生します。
やりたいのはa2のような基本クラスが6つほどあり、
a2のメンバ変数が多いので
コンストラクタの引数で指定されたものだけ
コンストラクタないでnewしたいのです。

なぜ、できないのか?
どうすればnewできるようになるのか…。
非常にお手数ですが、
どなたかご回答いただけませんでしょうか?
長文になりましたが、宜しくお願いいたします。

C++でお聞きしたいことがあります。
初心者ですのでご容赦ください。

//基本クラス
class a1
{
protected:
a1();
};

//派生クラス
class a2 :public a1
{
protected:
a2():a1(){};//継承先以外から作成されたくない
int t;
};

class a3 : public a2 //a2を継承
{
public:
a3();
~a3();
private:
a2*a;//a2のポインタを持つ
};

a3::a3()
{
t = 3;
a = new a2;//コンストラクタの中でnew
}

a3::~a3()
{
delete a;//終わったらdelete
}

int main(void)
{
a3a;

retu...続きを読む

Aベストアンサー

> しかしa3はa2をpublicで継承しているのに、
> なぜできないのかが疑問なのです。

今の状態でpublic継承に変更してみて、

a3::a3()
{
t = 3;
a = new a2; //コンストラクタの中でnew

の後で、
printf("this→%p, &t→%p, &a→%p, &(a.t)→%p\n",this, &t, a, &(a->t));
などとしてthisとaのアドレスを表示してみると、その時newされたaと自分自身(this)のアドレスが違うのが分かると思います。
自分自身(this)の外側でprotectで宣言されているものにはアクセスできません。

Q派生クラスから基本クラスprotectedメンバへのアクセスについて

C++初心者です。
以下のような基本クラスcoordと、その派生クラスquadがあり、quadクラスに関して=演算子をオーバーロードしました。

class coord
{
protected:
int x, y;
};

class quad : public coord
{
public:
quad operator=(coord &ob2);
};

quad quad::operator=(coord &ob2)
{
x = ob2.x;
y = ob2.y;
}

するとob2からxにアクセスできないとエラーが出ます。
quadクラスのメンバ関数内なので、基本クラスのprotectedメンバにはアクセスできると思ったのですが、違うのでしょうか。
ご教授お願いします。

Aベストアンサー

C++では、同じクラスであれば、別のオブジェクトのprotectedメンバにアクセスできます。
quad quad::operator=(quad &ob2)
{
x = ob2.x;
y = ob2.y;
}
は許されます。基底クラスであっても、同じ基底クラスから派生した別のクラスであっても、クラスが違えば、基底クラスでprotectedとされたメンバにはアクセスできません。

ところで、質問のプログラムの意図を満たすために、コンストラクタ
quad(coord&ob2):coord(ob2){};
を使うというのはどうでしょうか。

Qなぜprotected overrideなのか

C#でわからないことが2,3あるのですが、このmsndのサンプルで

public class FirstControl : Control{
public FirstControl() {}
protected override void OnPaint(PaintEventArgs e) {
// Call the OnPaint method of the base class.
base.OnPaint(e);
// Call methods of the System.Drawing.Graphics object.
e.Graphics.DrawString(Text, Font, new SolidBrush(ForeColor), ClientRectangle);
}
}

これのprotected override void OnPaint(PaintEventArgs e){}

の部分なのですが、なぜprotected overrinde修飾子なのでしょう
何をオーバーライドしてるのですか?他のサンプルにも構文のように出てくるのですが。

あとOnPaintはメソッドのようですがイベントを発生させるにはデリゲートではないのでしょうか

あとPaintEventArgsはクラスということですがnewはいらないのでしょうか。staticがどこかにあるのでしょうか
よろしくお願いします。

C#でわからないことが2,3あるのですが、このmsndのサンプルで

public class FirstControl : Control{
public FirstControl() {}
protected override void OnPaint(PaintEventArgs e) {
// Call the OnPaint method of the base class.
base.OnPaint(e);
// Call methods of the System.Drawing.Graphics object.
e.Graphics.DrawString(Text, Font, new SolidBrush(ForeColor), ClientRectangle);
}
}

これのprotected override void OnPaint(PaintEventArgs e){}

の部...続きを読む

Aベストアンサー

> の部分なのですが、なぜprotected overrinde修飾子なのでしょう
> 何をオーバーライドしてるのですか?他のサンプルにも構文のように出てくるのですが。
System.Windows.Forms.Control.OnPaintをoverrideしています。
元のメソッドがprotectedなので,可視性はprotectedのままになります。
overrideなので,継承元を辿っていけば元になるメソッドがあります。
http://msdn.microsoft.com/ja-jp/library/system.windows.forms.control.onpaint.aspx

> あとOnPaintはメソッドのようですがイベントを発生させるにはデリゲートではないのでしょうか
イベントを発生させることができるのは,イベントを定義したクラスのみです。
Paintイベントは,System.Windows.Forms.Controlのメンバなので,System.Windows.Forms.Control.OnPaintメソッドがイベントを発生させます。
また,イベントの前にOnが付いたprotected virtualなメソッドでイベントを発生させるのは,MSのガイドラインに沿った作りです。
http://msdn.microsoft.com/ja-jp/library/ms229011.aspx

> あとPaintEventArgsはクラスということですがnewはいらないのでしょうか。staticがどこかにあるのでしょうか
クラスのインスタンスが引数eに渡されてくるのです。
なので,なぜ「newはいらないのか」という発想になるのかが不思議です。
C#の文法をちゃんと勉強しましょう。
http://msdn.microsoft.com/ja-jp/library/ms173114.aspx
http://msdn.microsoft.com/ja-jp/library/51y09td4.aspx
http://msdn.microsoft.com/ja-jp/library/8f1hz171.aspx

> の部分なのですが、なぜprotected overrinde修飾子なのでしょう
> 何をオーバーライドしてるのですか?他のサンプルにも構文のように出てくるのですが。
System.Windows.Forms.Control.OnPaintをoverrideしています。
元のメソッドがprotectedなので,可視性はprotectedのままになります。
overrideなので,継承元を辿っていけば元になるメソッドがあります。
http://msdn.microsoft.com/ja-jp/library/system.windows.forms.control.onpaint.aspx

> あとOnPaintはメソッドのようですがイベントを発生させるに...続きを読む

QC++でfriendクラスにしているのにprivateメンバにアクセスできない

C++でメンバ変数をprivateにして、特定のクラスにだけ公開するようにクラスをfriend指定したのですがprivateメンバにアクセスできませんとエラーが吐かれてしまいます。

先行宣言したりもしてみたのですがどうしても使用できません。

何か心当たりのあるかた教えてください。

class A
{
friend class B;
private:
int a;
};

class B
{
public:
void test( A *a )
{
a->a = 0;
}
};

コードは違いますがこんな感じのことをしたいのです。

/*
コンソールで小さなプログラムでテストしてみると動くのにいざ実際のソースに組み込むと動かないという奇妙な状態です。よろしくお願いします。
*/

Aベストアンサー

 こんにちは。御礼頂き有難うございます。
 以下でコンパイルに通りました。

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;
}
};
}
}

Qメンバ変数の隠蔽

メンバ変数を隠蔽する方法を教えてください。

静的ライブラリをインクルードファイルとともに
配布しようとしております。

Q.通常、インクルードファイルを見れば、利用者に、
どのようなメンバ変数が使われているか知られて
しまいます。メンバ変数の存在そのものを隠蔽する
方法は無いでしょうか?

よろしくお願いいたします。

Aベストアンサー

> 継承や仮想関数などを使って実現できたように
> 記憶しております。

できますよ。使う側が変則的になりますが:

--- foo.h ---
class Foo {
public:
  virtual ~Foo() {}
  virtual void f() =0;
  virtual int g() =0;
  static Foo* create();
};

--- foo.cpp ---
#include "foo.h"

class FooImpl : public Foo {
public:
  virtual void f() { 処理 }
  virutal int g() { 処理 }
};

Foo* Foo::create() {
  return new FooImpl();
}


人気Q&Aランキング

おすすめ情報