
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で質問しましょう!
このQ&Aを見た人はこんなQ&Aも見ています
関連するカテゴリからQ&Aを探す
おすすめ情報
このQ&Aを見た人がよく見るQ&A
デイリーランキングこのカテゴリの人気デイリーQ&Aランキング
-
プログラム言語について c言語...
-
c++でテンプレートのコードでわ...
-
c言語
-
DLLファイルの逆コンパイラにつ...
-
C言語の関数のextern宣言
-
C言語について(初心者)
-
C言語について。
-
C言語をコンパイルするとコンピ...
-
C言語について。
-
変数名を引数として渡す、アド...
-
VisualStudioでC++クラスを追加...
-
スタックフレームの消滅
-
visual studio 2022でのC#プロ...
-
C言語 関数、変数の宣言について
-
c言語のリダイレクトによる円...
-
CPUが16bitでも32bitOSでコンパ...
-
0 == False はいいけど
-
インクリメント演算子のみを用...
-
C言語 配列と関数の練習問題
-
C言語の関数と配列に関する質問
マンスリーランキングこのカテゴリの人気マンスリーQ&Aランキング
-
VBA チェックボックスをオーバ...
-
FriendとPublicの違い。。。
-
イベントにAddHandlerされてい...
-
既定のコンストラクタがない?
-
ダイアログ表示時にチェックボ...
-
(UWSC) 「#32770」の意味わかり...
-
【ASP.NET】 独自で作成したク...
-
エディットコントロールでEnter...
-
クラスのアドレスを引数として...
-
WindowsAPIのリストビューの...
-
エディットコントロールのイベ...
-
MFCアプリのコマンドラインでパ...
-
ボタンのオーナードローについて
-
正規表現 [^/]+ の意味を教えて
-
C++ protectedにアクセス不可
-
このコンパイルエラーの意味に...
-
MFCのドラッグ&ドロップについて
-
C# 別プロジェクトのフォームを...
-
オーバーライド関数の呼び出し...
-
MFCのCListCtrlでスクロールを検出
おすすめ情報