2

クラスのコンストラクターで、次のように必要なサイズの配列を作成します。

ArrayClass::ArrayClass(int size) 
{
    Number* nmbr = new Number[size];
}

ArrayClass::ArrayClass()
{ 
    Number* nmbr = new Number[2];
}

また、ヘッダーで次のように指定しています

Number* nmbr;

配列自体の作成は機能しますが、コンストラクターの外ではアクセスできないようです。コンストラクターを離れるたびに、変数がメモリから解放されるようです。クラス内の他の関数を呼び出すときに変数を使用できるようにするにはどうすればよいですか?

4

3 に答える 3

6

新しい変数を作成しないでください。コンストラクター内のnmbrは互いに異なり、ヘッダー内の も異なります。

グローバルを使用する必要がある場合 (これを行うことについて 3 回考えてください)、それを として宣言しextern、単一の TU で定義して、単に使用します

 nmbr = new ArrayClass[2];

あなたのコンストラクタで。

記憶の整理や三の法則を忘れずに。

于 2013-01-17T15:06:08.217 に答える
2

コンストラクターではなく、クラスの宣言で変数 nmbr を宣言してみてください。例:

class ArrayClass

{

private: 

Number *nmbr;

public:

ArrayClass();

ArrayClass(int size);

~ArrayClass()

}

ArrayClass::ArrayClass(int size) 

{

this->nmbr = new Number[size];

}

ArrayClass::ArrayClass() 
{

this->nmbr = new Number[2];

}

ArrayClass::~ArrayClass()
{

delete this->nmbr;

}
于 2013-01-17T15:14:44.073 に答える
1

すべてのコードを 1 か所に配置すると、ここで問題を確認するのがおそらく最も簡単になります。

Number *nmbr;

class ArrayClass { 
    Number *nmbr;
public:

    ArrayClass() { 
        Number *nmbr = new Number[2];
    }
};

ここにあるのは、3 つの別々のスコープにある 3 つの完全に別々の変数です。それぞれが外側のスコープで同じ名前の変数を「隠します」。

これは、コンストラクターで初期化するときに、コンストラクター自体に対してローカルな変数のみを初期化することも意味nmbrしますctor が戻ると、そのポインターは破棄され、割り当てたメモリがリークされます。同様に悪いことに、ArrayClass::nmbr(ほぼ確実に) 初期化したかった はまだ初期化されていません。

クラスのnmbr外側にある はほぼ同じですが、1 つの点でわずかに安全です。グローバルであるため、ゼロで初期化されます。これはポインターであるため、null ポインターに初期化されることを意味します (したがって、データを指していませんが、少なくともテストが簡単で、そうでないことがわかります)。

これを防ぐには、おそらく変数の余分な定義を削除して、すべての参照nmbrが同じものを参照するようにする必要があります。

class Array { 
    Number *nmbr;
public:
    Array() : numbr(new Number[2]) {}
};

このクラスはリモート所有権を行っているように見える (つまり、ポインターを介してデータを割り当てて所有する) ため、5 の規則 (C++11 の古い 3 の規則の更新) に従う必要があります。代わりに a を使用すると、「ゼロの規則std::vector<Number>」に従うことができます。

于 2013-01-17T15:22:00.040 に答える