基底クラスclass1と派生クラスclass2でnewを使って同じサイズの2次元配列pとqを作ったのですが、メモリ内の同じ場所を参照してるみたいで、class2の配列qで配列の中身を書き換えたら、class1の配列pの中身も書き換えられているんですが、対処法があれば教えてください。

class class1{
protected:
     int** p;
public:
    class1(int n)
    {
  int i;
       *p=new int[n];
       for(i=0;i<n;i++){
         p[i]=new int[2];
       }
     }
   :
   :
};
class class2 : public class1{
    int** q;
public:
    class2(int n)
    {
  int i;
       *q=new int[n];
       for(i=0;i<n;i++){
        q[i]=new int[2];
       }
}
   :
   :
};

このQ&Aに関連する最新のQ&A

A 回答 (2件)

こうだと思う。



class CClassA
{
protected:
int** p;
int _nCntA;

public:
CClassA( int n ) {
_nCntA = n;
p = new int*[ n ]; // ポインタ配列を確保
for( int ii = 0; ii < n; ii++ ){
p[ ii ] = new int[ _nCntA ];
}
}
// デストラクタは省略
};

class CClassB : public CClassA
{
protected:
int** q;

public:
CClassB( int n ) : CClassA( n ) {
q = new int*[ n ]; // ポインタ配列を確保
for( int ii = 0; ii < n; ii++ ){
q[ ii ] = new int[ 2 ];
}
}
// デストラクタは省略
};
    • good
    • 0
この回答へのお礼

できました。たすかりました。ありがとうございました。

お礼日時:2002/01/30 19:21

最初にclass1::pとclass2::q(ポインタのポインタが指している先)がまだ不定なのにnew int[n]でアドレスをセットしているように見受けられますけど?


pとqの値(アドレス)によってはフリーズしちゃうと思います。

ためしてないけど。。。

この回答への補足

どうすればよいですか?

補足日時:2002/01/30 17:44
    • good
    • 0

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

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

Qfor(int i = 100, long n = 1; i > n/3i; i++)

for(int i = 100, long n = 1; i > n/3i; i++)
のように、初期設定で型の違う変数を宣言したいんだけど
C++ではこんなふうに2つ以上の型を宣言してはいけないんですか?

Aベストアンサー

,

コンマ演算子の原理です。
forの初期化文で "," で区切れるのは値を返す文だけです。
よってintステートメントもlongステートメントも値を返さないので、この文では使用できません。

というか、むしろ、intステートメントの第2引数としてlongが認識されてしまいます。
外で

int i; long n;

とし

for(i = 0, n = 0; hoge; hoge)

なら可能です。

Qint *a = new int; エラー

下記をコンパイルすると、'int' 型は 'int *' 型に変換できない(関数 main() )
とエラーが出てしまいました。 何がおかしいのでしょうか ?
初歩的な間違いをしていると思いますが、アドバイスお願いします。

#include<iostream>
#include<stdlib>
#include<ctime>
using namespace std;

void main(void)
{
int *a = new int;
a=rand();
cout<<a<<endl;
delete a;

}

Aベストアンサー

#include<iostream>
#include<cstdlib>
#include<ctime>
using namespace std;

int main(void)
{
srand ( time(NULL));
int *a = new int;
*a=rand();
cout<<*a<<endl;
delete a;
return 0;
}

/*
多分こうだと思う。
想像以上に乱数の精度が悪いような気がする。
*/

Qchar AA[]{"全角文字"};から"全"という一字を取り出したい

 今晩は、Cの初心者です、宜しくお願いします。
 全角文字の入ったchar AA[]{"全角文字"};から"全"という文字一字を取り出す時にAA[0]とかくとエラーになります。
 どのようにしたら取り出せるのでしょう。
 ポインタを使う方法と使わない方法を教えて下さい。
 宜しくお願いします。

Aベストアンサー

お疲れ様です。

まずお伺いしたのがOSおよび開発するためのコンパイラです。

ロケール等の話は分かりませんが、昔のC言語で日本語を扱う場合には全角文字1文字で2個つのchar領域を使用していました。
(マルチバイト文字セットと言います。)

詳細は参考URLを参照の事。

windowsでVCと仮定した場合、charを使われていると言うことは、多分、shift-jis(シフトJIS)で文字列を扱っていると思われます。

結論として全角文字1文字だけを取り出したいという場合は、結局char2個分のデータを取り出す必要があります。

>char AA[]={'全','角'};

char AA[]="全角";
とし
>printf("%s%s\n" , AA[0],AA[1] ) ;

printf("%c%c\n" , AA[0],AA[1] ) ;
とすれば、「全」だけを表示する事が可能と思われます。

日本語を文字列で表示する為の文字コードについては
Shift-JISだけでなく、UnicodeやUTF・EUC・JISなどがあります。

もう少し詳しく記載してあるホームページはないか探してみましたが、ちょっと無理でした。

参考URL:http://marupeke296.com/CPP_charUnicodeWideChar.html

お疲れ様です。

まずお伺いしたのがOSおよび開発するためのコンパイラです。

ロケール等の話は分かりませんが、昔のC言語で日本語を扱う場合には全角文字1文字で2個つのchar領域を使用していました。
(マルチバイト文字セットと言います。)

詳細は参考URLを参照の事。

windowsでVCと仮定した場合、charを使われていると言うことは、多分、shift-jis(シフトJIS)で文字列を扱っていると思われます。

結論として全角文字1文字だけを取り出したいという場合は、結局char2個分のデータを取り出...続きを読む

Qint i, int i[1];

C++で、
 int i;
と、
 int i[1];
は、どっちで宣言をしても、iは同じ振るまいですか?

Aベストアンサー

配列、ポインタなどよりももっと基礎的な概念である「右辺値」、「左辺値」を理解しましょう。

int i ;
この形で宣言されたiは代入式の右辺(代入する値)にも左辺(代入される領域)にも使うことが出来ます。
int a ;
a = i ;
i = 10 ;

C言語でも他のほとんどの言語でも「変数は右辺の時と左辺の時とでは解釈が違う」という原則があります。

代入式の右辺に配置出来るのは『値』です。
変数であっても良いし定数であっても、式であってもかまいません。
左辺がポインタ変数の場合は右辺はアドレス値(またはアドレス式)です。
代入式の右に配置可能な値を右辺値といいます。

代入式の左に配置出来るのは『領域』です。
変数であっても良いし、配列要素でもかまいません。
また、領域を示す式(int i[1]のときの*iなど)でもかまいません。
配列名(int i[1]のときのi)や定数は領域を持たないため、左辺に配置することが出来ません。
代入式の左に配置可能な領域を左辺値といいます。

int i[1] ;
この形で宣言されたiは右辺値に利用できます。
int *a ;
a = i ;
しかし、iだけでは領域を持たないため左辺値になりえません。
i = 1 ; //コンパイルエラーが出る。

コンパイル時に「有効な左辺値でない」と言う意味のエラーが出るのは「領域を示さない値を左辺値として使っている時」です。

どちらかと言うと「基礎理論」の部類なのでプログラム言語の本などには書いてないのですが、実は最も大切なのが「基礎理論」です。
頑張って勉強してください。

配列、ポインタなどよりももっと基礎的な概念である「右辺値」、「左辺値」を理解しましょう。

int i ;
この形で宣言されたiは代入式の右辺(代入する値)にも左辺(代入される領域)にも使うことが出来ます。
int a ;
a = i ;
i = 10 ;

C言語でも他のほとんどの言語でも「変数は右辺の時と左辺の時とでは解釈が違う」という原則があります。

代入式の右辺に配置出来るのは『値』です。
変数であっても良いし定数であっても、式であってもかまいません。
左辺がポインタ変数の場合は右辺はアドレス...続きを読む

Qtry{}catch(){}とデストラクタの関係を教えてください。

try-catchでメモリ確保を含むクラスをスローした場合、デストラクタはどの時点で働くのか、教えてください。たとえば、↓の使いかたは大丈夫でしょうか?

【1】
try{
 throw(CError(100, "エラー情報"));
}catch(CError& err){
 //ここでerrを参照しても問題ないのでしょうか?
}

【2】
try{
 CError err(100, "エラー情報");
 throw(err); // (1)
}catch(CError& err){
 //ここでerrを参照しても問題ないのでしょうか?
 //まだデストラクタはちゃんと動作するのでしょうか?
 //catchが呼び出し元のメンバであったりしても大丈夫なのでしょうか?
}

宜しくお願いします。

Aベストアンサー

【1】【2】どちらの場合も問題がありません。
コンパイラが必要に応じてerrオブジェクトのコピーを作成します。
デストラクタが呼び出されるタイミングはコンパイラに依存するところもあると思いますが、
例えばVC7.1では【2】は以下のように動作します。
(1) errオブジェクトのコンストラクタが呼び出される
(2) CErrorクラスのテンポラリオブジェクト(以下a)のコピーコンストラクタが呼び出される。
(3) errオブジェクトのデストラクタが呼び出される
(4) catch文まで到達
(5) aオブジェクトのデストラクタが呼び出される。

VC7.1では、【1】は以下のように動作します。
(1) errオブジェクトのコンストラクタが呼び出される
(2) catch文まで到達
(3) errオブジェクトのデストラクタが呼び出される。

コンパイラがオブジェクトのコピーを省略しているようです。


人気Q&Aランキング

おすすめ情報