0

私は次のようにクラスPersonを持っています:

class Person {   
    char* name;
    int age;
};

次に、2つのコンストラクターを追加する必要があります。引数を取らないもので、動的に割り当てられたリソースにフィールド値を挿入します。初期化リストによって初期化された2番目の(char *、int)引数を取ります。最後の部分は、オブジェクトの破棄と動的に割り当てられたリソースの割り当て解除に関する情報を表示するデストラクタを定義することです。このタスクを実行する方法は?

それは私がすでに持っているものです:

class Person {   
    char* name;
    int age;
public:
    Person(){
        this->name = new *char;
        this->age = new int;
    }

    Person(char* c, int i){
    }
};
4

5 に答える 5

3

デフォルトのコンストラクターでは、char配列の割り当てには、必要なサイズを含める必要があります。

this->name = new char[32];

このサイズには終了0文字が含まれているため、この配列に格納できる名前の有効な長さは31であることに注意してください。

パラメーター化されたコンストラクターでは、指定されたパラメーターをクラスメンバーに割り当てるだけです。

デストラクタでは、動的に割り当てられたリソースの割り当てを解除する必要があります。次の方法delete[]で割り当てられたメモリの割り当てを解除する場合にのみ使用してnew[]ください。

~Person(){
    std::cout << "Destroying resources" << std::endl;
    delete[] name;
    delete age;
}

更新:これを見逃しました:age動的に割り当てる場合は、として宣言する必要がありますint* age

この演習のポイントは、動的な割り当て/割り当て解除を練習することだと思います。この文脈では、それは問題ありません。ただし、一般に、を動的に割り当てることはお勧めできません。int代わりに、char*ほとんどの場合std::string、メモリ割り当てを自動的かつ安全に処理するを使用する必要があります。

于 2010-05-18T10:00:55.343 に答える
2

C ++stringクラスを使用すると、手動の(そして危険な)メモリ管理を忘れることができます。

class Person {
    public:
        Person () : name_(""), age_(0) { }
        Person (const std::string& name, int age) : name_(name), age_(age) { }
    // There is no need for the destructor as the memory is managed by the string class.
};

コンストラクターでの割り当てではなく、常に初期化リストを使用する必要がある理由についても、このリンクを参照してください。

于 2010-05-18T10:43:45.927 に答える
1

宣言では、はポインタではないため、動的に割り当てられたメモリに初期化することはできません。ageage

もちろん、タイプをageに変更することもできint*ます。しかし、私はそれをしません、それは目的を果たしません。割り当てが実際に動的割り当てを要求しているかどうかは明らかではありません(もしそうなら、なぜですか?)。

name一方、の場合は、@Péterで示されているように続行できます。stringしかし、繰り返しになりますが、C ++は文字列操作をクラスにうまくラップするクラスを提供するため、これはほとんどの場合あまり良い解決策ではありません。割り当てでこれが許可されている場合は、動的メモリ割り当てstringの代わりに使用します。char*

于 2010-05-18T10:12:26.123 に答える
0

char*の代わりにstringクラスを使用することをお勧めします。

このようなもの:

class Person
{
 public:
  Person() : name(""), age(0) {}
  Person(const string& n, int a) : name(n), age(a) {}

  // whatever here.

  ~Person() {} // do nothing

 private:
  string name;
  int age;
};
于 2010-05-18T11:34:12.447 に答える
0

名前を設定するときに、名前をコピーするために必要なメモリだけを割り当てることもできます。また、オブジェクトが破棄されたときに、割り当てられたバッファを解放することを忘れないでください!

class Person {   
    char* name;
    int age;
public:
    Person(){
        this->name = NULL;
        this->age = 0; // no need to allocate memory for basic types
    }

    ~Person(){
        delete [] name;
    }

    set(char* c, int i){
        this->age = i;

        // copy name if input pointer name is valid
        if (c != NULL){
            // if memory have already been allocated : delete first
            if (this->name != NULL){
                delete [] name;
                name = NULL;
            }
            // allocate memory : 1 more char for the trailing '\0'
            this->name = new char[strlen(c)+1];
            // copy string
            strcpy(this->name,c);
        }
    }
};

編集してコメントに答える:

  • コンラート・ルドルフの提案による簡略化されたデストラクタ
  • ポインタが正しく使用されていないときにランダムなメモリ位置が選択されないように、割り当てられていないポインタと割り当て解除されたポインタを常にNULLに設定する傾向があります。また、割り当てられていないポインタはdebbugerで見つけやすくなります。
  • 2番目のメソッドがコンストラクターであることに注意を払いませんでした。セッターだと思いました...変更しました。
于 2010-05-18T10:11:59.967 に答える