0

小さなプログラムを書きましたが、メインのデストラクタが正しく動作しません。プログラムのコードは次のとおりです。

#include<iostream.h>

class citizen {
private:
    char* name;
    char* nationality;
public:             
    citizen(char* name, char* nationality) {
        this->name = name;
        this->nationality = nationality;
    }                  

    citizen(const citizen &obj) {
        name = obj.name;
        nationality = obj.nationality;
    }        

    void display() {
        cout << "Name: " << name << endl;
        cout << "Nationality: " << nationality << endl;
    }

    ~citizen() { 
        if(name){
            delete[]name;
        }
        if(nationality) {
            delete []nationality;                          
        }        
    }       
};

main() {
   citizen obj1("Ali", "Pakistani");
   obj1.display();
   { 
      citizen obj2 = obj1;                 
   }
   obj1.display();
   system("pause");
}

私が知っているのは、 tomainの状態を割り当てている関数で、その場所から両方が同じメモリ領域を指していることです。コードは 2 つの中かっこの間にあります。obj1obj2citizen obj2 = obj1;

   { 
      citizen obj2 = obj1;                 
   }

したがって、2 番目の中括弧の実行後、obj2変数namenationality. そして、2回目に呼び出すobj1.display();と、画面にゴミが表示されるはずです。

しかしobj1、そうであってはならないにもかかわらず、コンストラクターで提供した正確な名前をまだ出力しています。

この動作を説明してください。

4

7 に答える 7

3

文字列リテラルを破棄しようとしているため、あなたdelete[]の s は未定義の動作を呼び出します。何でも起こりえます。

自分でメモリを割り当てたとしても、既に削除したメモリにアクセスしようとするため、未定義の動作が発生します。

obj1.display();
{ 
   citizen obj2 = obj1;                 
}
obj1.display();  // ILLEGAL

代入演算子を定義していないため、コンパイラによって生成された演算子が使用されます。これは、ポインタを同じメモリ (破棄してからアクセスしようとするメモリ) に割り当てるだけです。

于 2013-10-07T13:33:50.820 に答える
0

みんなありがとう。このコンストラクターのコードを置き換えました

citizen(char* name, char* nationality) {
    this->name = name;
    this->nationality = nationality;
}        

このコードで

citizen(char* name, char* nationality){ 
   this->name = new char[strlen(name)+1]; 
   strcpy(this->name, name); 
   this->nationality = new char[strlen(nationality)+1]; 
    strcpy(this->nationality, nationality); 
} 

そして最後にそれはうまくいきます。ありがとう

于 2015-03-29T16:29:16.393 に答える