
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できるようになるのか…。
非常にお手数ですが、
どなたかご回答いただけませんでしょうか?
長文になりましたが、宜しくお願いいたします。
No.3ベストアンサー
- 回答日時:
> しかし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で宣言されているものにはアクセスできません。
No.4
- 回答日時:
VC6,VC.NET,GCCで試してみました。
どれもコンパイルできませんでした。
試しにa1に別の関数をprotectedで宣言してa3コンストラクタからアクセスすると問題ないようです。
どうやらコンストラクタのみアクセスできないようですね。
私も知りませんでした。
他の方がprotectedではアクセスできないと書かれていますが、コンストラクタ以外なら全てアクセスできます。(なので、他の方は質問の意味を誤解されてるのではないでしょうか?)
なぜコンストラクタだけアクセスできないのでしょう?
理由を考えてみましたが思い当たりませんでした。
MSのみでなくGCCもそうなので、おそらく仕様なのでしょう。
残念です。
解決策としては、friend a3をa2で宣言するしかないようですね。
newせずに普通にメンバとしてインスタンスを持たせることは
できますので、
#1様が仰っていたとおりなのでしょうね?…。
解決策をご教授していただいてありがとうございました。
friendすることにより
解決いたしました。
No.2
- 回答日時:
a3::a3()の中で
a2のインスタンスを作成してどないすんの。
何か勘違いしていませんか?
コンパイルエラーの意味は、
int main(void)
{
a2 *a = new a2;
}
というのが出来ないのと同じ理由ですよ。
派生クラスa3で親クラスのa2のメンバ変数tに
アクセスしたいだけならその一文はいらないです。
a3::a3()
{
t = 3;
}
この回答への補足
質問がわかりづらくて申し訳ありません。
main の中で a2 のインスタンスが
作成できない理由はわかります。
a2のコンストラクタがprotectedですから…。
しかしa3はa2をpublicで継承しているのに、
なぜできないのかが疑問なのです。
別段、t3にアクセスしたいために
a2のインスタンスを作成したいわけではないのです。
No.1
- 回答日時:
> なぜ、できないのか?
a2::a2()はprotectedですので、これを継承したクラスのオブジェクト、インスタンスの中で使えます。
a3::a3()
{
t = 3;
a = new a2; //コンストラクタの中でnew
}
の処理ですと、aに代入されるa2クラスのインスタンスのアドレスは、a3=a2のアドレスと異なるものです。
アドレスが異なる→置き場所が異なりますから、これは別のオブジェクトという事になりますので、自分自身の中身で無いのでアクセスできないという事になります。
--
> どうすればnewできるようになるのか…。
しばらくコーディングから遠ざかっていたので、適切なクラスの構成が思いつきません。
friendを使うのかな?(自信なし)
う~んと…
かなり難しいです。
意味はわかりませんが、
friend関数を使うとよろしいのでしょうか?
さっそく調べてみます。
回答ありがとうございました。
お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!
似たような質問が見つかりました
- C言語・C++・C# C#テキストボックスの文字を配列にいれてその後表示する 4 2022/07/17 04:47
- Java JavaのSingletonパターンのprivateの持つ意味が分かりません。 5 2022/06/12 10:38
- 数学 a1,a2, a3をベクトル空間Vのベクトルとする。a1+a2,a2+a3,a3+a1が一次独立のと 2 2022/10/02 15:55
- 数学 行列の問題が分かりません。 3次正則行列Aの列ベクトル分割をA=(a1 a2 a3)とおくとき,次を 4 2022/06/23 08:34
- Java java final 1 2022/06/10 22:49
- Excel(エクセル) エクセルで、指定した整数の範囲を乱数4つ発生させる場合 4 2022/04/01 11:44
- その他(プログラミング・Web制作) Excel の判定式で正しく判定されない場合があります。 2 2022/05/31 14:43
- Java java 入力 3 4 3 出力 ABC DEFG HIJ このようなプログラムの書き方を教えてくだ 2 2022/07/15 14:18
- 数学 3次元実ベクトル空間において, 平面 P:x-y+z+1=0 と直線 L:2(x-1)=-y=-z 3 2022/10/29 14:39
- 数学 線形代数の正規直行系についての問題がわからないです。 1 2022/07/16 11:20
このQ&Aを見た人はこんなQ&Aも見ています
関連するカテゴリからQ&Aを探す
おすすめ情報
このQ&Aを見た人がよく見るQ&A
デイリーランキングこのカテゴリの人気デイリーQ&Aランキング
-
イベントにAddHandlerされてい...
-
エディットコントロールでEnter...
-
このコンパイルエラーの意味に...
-
FriendとPublicの違い。。。
-
OnPaintとOnDraw関数の違いにつ...
-
ダイアログクラスのコントロー...
-
WindowsAPIのリストビューの...
-
VC++でダイアログ表示について
-
VBA チェックボックスをオーバ...
-
ダイアログ表示時にチェックボ...
-
【ASP.NET】 独自で作成したク...
-
メンバ変数のサイズの増加
-
クラスのアドレスを引数として...
-
オーバーライド関数の呼び出し...
-
MFCアプリのコマンドラインでパ...
-
モーダレスなメッセージボック...
-
IncludeではなくClassで宣言す...
-
リストコントロールをウィンド...
-
クラスの設定について
-
C#でExcelを起動したい
マンスリーランキングこのカテゴリの人気マンスリーQ&Aランキング
-
VBA チェックボックスをオーバ...
-
FriendとPublicの違い。。。
-
既定のコンストラクタがない?
-
イベントにAddHandlerされてい...
-
(UWSC) 「#32770」の意味わかり...
-
ボタンのオーナードローについて
-
MFCアプリのコマンドラインでパ...
-
ダイアログ表示時にチェックボ...
-
【ASP.NET】 独自で作成したク...
-
エディットコントロールでEnter...
-
MFCのドラッグ&ドロップについて
-
オーバーライド関数の呼び出し...
-
DataGridViewのセルに斜線を引...
-
MFCのCListCtrlでスクロールを検出
-
C++ protectedにアクセス不可
-
ダイアログクラスのコントロー...
-
クラスのアドレスを引数として...
-
エディットコントロールのイベ...
-
個々の関数について継承してい...
-
WindowsAPIのリストビューの...
おすすめ情報