0

私はC++(Javaから来た)の初心者で、クラスで配列オブジェクトを宣言したいのですが、テンプレートパラメーターに整数値が必要です。配列クラスへのポインターを作成する必要があると考えましたが、機能しません..

私は次のようなものを作りたい:

class foo{
    private:
        array *myArray;
    public:
        foo(int size){
            //This line may be terribly wrong, but you see what I mean
            myArray = new array<int,5>(); 
        }
        ~foo(){
            free(myArray);
        }
}

ただし、配列オブジェクトの正しい初期化は次のとおりです。

array<int,5>

しかし、この方法では実行時に長さを選択できません。

4

4 に答える 4

12

優れた C++ の入門書を手に取り、 Java のことは忘れることを強くお勧めします。真剣に、Java で考えることは、C++ を学ぶときに逆効果です。構文は似ているかもしれませんが、非常に異なるセマンティクスを持っています。

あなたが抱えている問題は、言語の基本的な概念に関連しています。先に進む前に、優れた C++ 入門書から基礎を学ぶ必要があります。


std::array(それが使用している場合) は、実行時に長さを選択する必要があるため、この特定のアプリケーションに使用する正しいクラスではありません。のサイズはstd::arrayコンパイル時に固定されます。

代わりに使用する必要がstd::vectorあります。これにより、実行時にサイズを指定 (および変更) できます。

などの標準コンテナstd::vectorがメモリを管理します。newまたはdelete標準のコンテナを使用する必要はありません。標準コンテナが存在するのは、自分でメモリを手動で処理する必要がないためです

#include <vector>

class foo
{ 
private: 
    std::vector<int> myArray; 
public: 
    foo(int size) : myArray(size) // Sets the size of the array
    {
    } 

    ~foo()
    { 
        // You don't need to delete anything; the vector takes care of itself.
    } 
};

newここでは、 、deletemalloc()、またはポインターを使用していないことに注意してfree()ください。C++ では、非常に多くの場合、ポインターは必要ないことがよくあります。一般に信じられていることとは反対に、最新の C++ 手法を使用する場合、実際に行う必要がある手動のメモリ管理はほとんどありません。実際、 C++ コードでdeleteorfree()を使用している場合は、おそらく非常に間違っています。

言語を理解する上で、優れた C++ 入門書の重要性を再度強調したいと思います。優れた C++ の入門書はstd::vector、それを有利に使用する方法をカバーしています。リファレンスなどstd::vectorの他のリソースも役立ちます。それらに慣れてください。

于 2012-07-08T05:52:02.367 に答える
2

あなたが探しているのはvectorクラスだと思います。これは、連続した配列のようなストレージ構造 (素晴らしいスタックオーバーフローの質問です) であり、C 配列に代わる C++ です。

ポインターを使用して実行できますが、vector動的にサイズが大きくなるため、それほど重要ではありません。

あなたの例からの例は次のとおりです。

#include <vector>

class foo{
    private:
        std::vector<int> *vecPointer;
    public:
        foo(int size){
            vecPointer = new std::vector<int>(size, 0);
                // 0 as default value, can be omitted
        }
        ~foo(){
            delete vecPointer;
        }
}

メモリを予約したいだけで、クラスの初期化時に実際には要素を持っていない場合の代替手段は、メモリを具体的な値で埋めるのではなく、メモリを予約intすることです。その場合、コンストラクタは次のようになります。

foo::foo(int size){
     vecPointer = new std::vector<int>();
     vecPointer->reserve(size);
}

デストラクタは変更されず、 内ではclass foo、 で予約サイズまでオブジェクトをvecPointer->push_back(5)追加でき、それ以上のオブジェクトをまったく同じ方法で追加できます(その後のみ、ベクトル サイズとそれが必要とするメモリが増加します)。

また、本当にポインターを使用しますか? 必要はありません。法線ベクトルを使用できます。

#include <vector>

class foo{
    private:
        std::vector<int> vec;
    public:
        foo(int size){
            vec.resize(size, 0); // it's initialized as empty here
            // alternative, with reserve:
            // vec.reserve(size);
        }
        ~foo(){
            // no deletion needed like this
        }
}

このようにして、すべてが処理され、削除を覚えておく必要がなくなります。

于 2012-07-08T05:54:18.420 に答える
0
foo(int size) {
    myArray = new int[size];  // Allocate n ints and save ptr in a.
    for (int i=0; i<size; i++) {
        myArray[i] = 0;    // Initialize all elements to zero. 
}
于 2012-07-08T05:54:34.643 に答える
0

他の回答は質問にうまく答えています(メモリを管理する必要はありません)が、メモリを自分で管理したいとします( new 演算子を使用)-

次に、Unique ポインター (スマート ポインター) を使用して配列をポイントします。

#include <memory>

class foo{
    private:
        std::unique_ptr<int> myArray;
    public:
        foo(int size){
            myArray.reset(new int[5]); 
        }
        ~foo(){
        }
}

ここでメモリを解放する必要はありません (ベクターと同様)。

ただし、最善の解決策はベクトルを使用することです (指摘されているように)。ただし、質問のタイトルに「配列へのポインター」と書かれているため、配列をスマートに指す方法を追加しました。

于 2012-07-08T06:27:18.437 に答える