2012-02-02 7 views
0

主な問題は、動的クラスを作成することです。私がやった:私はポインタptrが指すサイズ2の動的配列を作成しようとしているクラスとポインタ、どのように動作するのですか?

ptr = new animal[2]; 

。私はこれらの操作をしようとすると、 問題が発生する:

ptr[0].setspeed(9); 
ptr++->setspeed(13); 

私はDDD(GDBのグラフィカル)デバッガを使用していますが、私はPTRを表示するとき、私はそれが一つのオブジェクトを指す参照してください。速度を設定しようとすると、最初のものは動作しているように見えますが、2番目のものは動作しません(速度はデフォルトの0です)。印刷はゴミだけを取得します。

私は何が起こっているか分かりませんので、助けてください。

また私が行うとき:

ptr->print(); 

はそれがptr[0]ptr[1]、またはちょうどptr[0]の両方に印刷することになっていますか?

さらに、ptrと新しいダイナミッククラスの外観をすばやく描くことができますか?私がそれを見る方法は、配列を指すptrであり、配列の大きさは2で、それぞれには動物オブジェクトがあります。

#include <iostream> 
using namespace std; 

class animal 
{ 
    private: 
     int speed; 
     double position_x; 
     double position_y; 

    public: 
     animal() : speed(0), position_x(0), position_y(0) 
     { 
     } 

     animal (int v, double x, double y) 
     { 
      this->speed = v; 
      this->position_x = x;  
      this->position_y = y; 
     } 

     animal(const animal & g) 
     { 
      this->speed = g.speed; 
      this->position_x = g.position_x; 
      this->position_y = g.position_y; 
     } 

     ~animal(); 

     void print(); 

     int getspeed() { return this->speed; } 

     int getx() { return this->position_x; } 

     int gety() { return this->position_y; } 

     void setspeed(int s) { this->speed = s; } 
    }; 

    void animal::print() 
    { 
     cout << "speed: " << this->getspeed() << endl; 
     cout << "position_x: " << this->getx() << endl; 
     cout << "position_y: " << this->gety() << endl; 
    } 

    int main() 
    { 
     animal *ptr; 
     ptr = new animal; 
     ptr = new animal [2]; 

     ptr[0].setspeed(9); 
     ptr++->setspeed(13); 

     ptr->print(); 
     cout << ptr[0].getspeed() << endl; 
     cout << ptr[1].getspeed(); 

     return 0; 
    } 
+5

ベスト・ヘルパー:動的配列をねじ込み、 'std :: vector'を得る。 – Xeo

+0

ありがとう、しかし私はこれを理解したい(私は本当にこれを理解したいという意味です)、それが私がやっている理由です。 私は "ベクトル"に感謝 – Rave

+2

"ptr =新しい動物; ptr =新しい動物[2];"たぶんこれは単にタイプミスかもしれませんが、メモリリークです。 – Duck

答えて

5

私のC++は錆びですが、ここで私が何を考えてだ:

ptr++->setspeed(13); 

これはポストインクリメントです。 ptrであり、最初にと評価され、となり、が増加する。つまり、ポインタの元の値に対してsetspeedが呼び出されます。

個人的には、このコードのスタイルは受け入れられないと私はこれを書いている誰もが発砲すると思います。読むのが難しく、読みやすく理解しやすいはずです。代わりに

ptr[0].setspeed(9); 
ptr++->setspeed(13); 

+0

未定義の動作です。 :) – Xeo

+0

また、配列の先頭に戻るためにポインタを減らすことを忘れないでください。 – Beta

6

あなたが使用することができ、より直感的で、より正確な

ptr[0].setspeed(9); 
ptr[1].setspeed(13); 

あなたが++を行うと、それはを指すようになりますので、あなたは、PTRの値を変更しています次の要素。後で[]を削除できるように、配列の先頭にポインタを置いてください。

また、ptr ++はポインタをインクリメントしますが、の古い値を返します。おそらく(++ ptr) - > setspeed(13)が必要になります。これは、式の残りの部分での新しい値をインクリメントして使用します。

その他の質問として、ptr->print()ptr[0].print()と同じで、(ptr+1)->print()ptr[1].print()と同じです。すべての要素にを呼び出すための組み込み構文はありません。

6

[OK]を、誰かがすでにthe memory leak issueを指摘しました。

したがって、2匹の動物(ptr = new animal [2];)の配列を割り当て、最初のものへのポインタをptrに格納しました。

+----------+----------+ 
| speed: 9 | speed: 0 | 
+----------+----------+ 
    ^
    | 
    | 
    ptr 

+----------+----------+ 
| speed: 0 | speed: 0 | 
+----------+----------+ 
    ^
    | 
    | 
    ptr 

は、その後、あなたが9(ptr[0].setspeed(9);)への最初の1の速度を設定(私はスペースの都合上、position_xposition_yを無視しています)

あなたは何か非常に奇妙なことをします。

ptr++->setspeed(13); 

なぜこれを行うのかわかりません。これをしないでください。私は冗談ではない。私はこのコードの意味を理解することができますが、私はこのようなことを書くことはありません。それは混乱を起こすためだけに役立ちます。

しかし、それはしばらくの間は普通のことですが... ptr++はポインタを増分し、古い値を返します。

+----------+----------+ 
| speed: 9 | speed: 0 | 
+----------+----------+ 
    ^  ^
     |   | 
     |   | 
    result  ptr 
    of ptr++ 

...そして、それは13

+-----------+----------+ 
| speed: 13 | speed: 0 | 
+-----------+----------+ 
    ^  ^
     |   | 
     |   | 
    result  ptr 
    of ptr++ 

にその結果が指し示す動物の速度を設定最後に、ptr->print()は、第二の一つであるptrによって指し示さ動物を印刷します。

+0

私はptr ++を実行した後、私はptr [1]を呼び出します。もしdelete [] ptrを呼び出すと、ptr [1]だけが削除され、ptr [0]はメモリリードになりますか? – Rave

+0

@Rave:実際、それは悪いことです。 'new []'によって提供されたポインタを '[]'だけ削除することができるので、 'delete [] ptr'は2番目のポインタを指しているので未定義の動作になります。ポインタを 'delete []'の先頭に戻す必要があります。 –

0

++演算子が変数(ptr ++)の後にある場合は、最初に評価と増分を行います。 それはこの文を意味

ptr->setspeed(13) // ptr point to animal[0] 
ptr++    // ptr point to anima[1] after this statement 

そして++ ptr-> setspeed(13)として

ptr++->setspeed(13); 

作品は逆の方法で動作します。

ここで問題の原因を確認できます。あなたは実際に動物[0]にsetspeed(13)を、動物[1]にprint()を呼び出します。

+0

オペレータの優先順位に注意してください。 ++ ptr-> setspeed(13)は++(ptr-> setspeed(13))を意味します。つまり、関数呼び出しの戻り値(存在する場合)をインクリメントします(テストされていませんが、 //msdn.microsoft.com/en-us/library/126fe14k%28v=vs.71%29.aspx]を参照してください)。 – marcus

+0

はい。それは(++ ptr) - > setspeed(13)でなければなりません。 –

関連する問題