0

これは、cpp コードを計算する単純な四角形の領域です。これについていくつか質問があります。

#include <iostream>
#include <conio.h>
using namespace std;
class CRectangle
{
        int *width, *heigth;
    public:
        CRectangle(int, int);
        ~CRectangle();
        int area() { return (*width * *heigth);}
};

CRectangle :: CRectangle(int a, int b)
{
    width = new int;
    heigth = new int;
    *width = a;
    *heigth = b;
}

CRectangle :: ~CRectangle()
{
    delete width;
    delete heigth;
}

void main()
{
    CRectangle rect1(3,4), rect2(5,6);
    cout << "rect1 area = " << rect1.area() << "\n";
    cout << "rect2 area = " << rect2.area();
    getch();
}
  1. なぜそのようなオブジェクト指向コードでポインタを使用するのですか?つまり、利点は何ですか?
  2. このコードでは、作成したオブジェクトrect1(3,4)を作成した後、これrect2(5,6)を行うと、論理的に (私が思うに) 幅と高さが指しているメモリセクションで 3 と 4 の代わりに 5 と 6 が置き換えられるため、3 と 4 はもう使用できません。しかし、彼らはです。

正確に何が起こるか説明してください。

4

4 に答える 4

3

1-なぜそのようなオブジェクト指向コードでポインタを使用するのですか?つまり、利点は何ですか?

ありません。

2、3、4

    width = new int;
    heigth = new int;

各コンストラクター呼び出しで常に新しい個別のメモリ位置を予約しています。すべてのオブジェクトには、幅と高さの個別のメモリ ロケーションがあるため、上書きはありません。

ただし、2 つのオブジェクトが同じメモリ位置を共有する場合があります。コピー コンストラクターまたは代入演算子を使用して、あるオブジェクトを別のオブジェクトにコピーする場合です。

CRectangle rect1(3,4);
CRectangle rect2 = rect1;
CRectangle rect3(4, 5);
rect3 = rect1;

この場合、widthと とheight同じ値を取得するとrect1、3 つのオブジェクトすべてが同じメモリ位置を指すようになります。の場合rect2、デフォルトのコンストラクターは呼び出されないため、新しいメモリは割り当てられません。 の場合、とrect3の古い値は失われ、変数はメモリ位置で更新されます。メモリ リークに (の既定のコンストラクタで割り当てられたメモリは決して解放されないため)。widthheightrect1rect3

于 2013-09-06T17:23:56.653 に答える
2

あなたの場合、ポインタは何も与えません。

したがって、ポインタは配列であることを証明するには、演算子の[]インライン実装を見てください。a[b]実際にはあり*(a + b)ます。したがって、new単一の値を作成するために使用する場合(あなたの場合)、それは悪い経験です。それを使用して配列を作成できます。この場合の利点は、newメモリを使用して作成するとヒープに割り当てられ、通常の方法でメモリを作成するとスタックに割り当てられることです。 .

C++ はプログラマーがポインターを必要とするかどうかを選択できるようにこれを残しました。たとえば、コンテナーを使用してメモリ割り当てに関する利点を得ることができstd::vector、この方法ではエラーが発生しにくくなります。

もう 1 つのことは、C との互換性のために C++ に残されたポインタです。C で書かれたものはたくさんありますが、C++ 開発者もそれを使用しているためです。


width と height が指しているメモリ セクションの 3 と 4 の代わりに 5 と 6 が置き換えられるため、3 と 4 は使用できなくなります。

この文を読んだら、C++ やその他の目的指向プログラミング言語について読む必要があると思います。

私の簡単な説明は、なぜすべての値がアクセス可能でrect1ありrect2、完全に異なる独立したオブジェクトであるため、それらは独自の記憶を持ち、互いに影響を与えることができないということです。


ところで:ヒープでの割り当ての欠点について言及するのを忘れていました-スタックでの割り当てよりもはるかに遅いです。

于 2013-09-06T17:28:39.143 に答える
0

なぜそのようなオブジェクト指向コードでポインタを使用するのですか?つまり、利点は何ですか?

ここには利点はありません...理由をいくつか説明します。

次のようないくつかの欠点があります。スタックでの割り当てよりもはるかに遅いヒープでの割り当て。

このコードでは、オブジェクト rect1(3,4) を作成した後、 rect2(5,6) を作成します。これにより、論理的に (私が思うに) 5 と 6 は、幅と高さがメモリ セクションで 3 と 4 の代わりに置き換えられます。を指しているため、3 と 4 はもう使用できませんが、使用できます。

作成された各オブジェクトには、独自のメモリ空間はありません。

CRectangle rect1(3,4), rect2(5,6);

ここでは、2 つの異なるオブジェクトを作成します。作成された 2 番目のオブジェクトは、最初のオブジェクトのメモリを使用しません。widthしたがって、各オブジェクトには、およびheightメンバー用の独自のスペースがあります。

于 2013-09-06T17:26:33.573 に答える
-1

なぜそのようなオブジェクト指向コードでポインタを使用するのですか?つまり、利点は何ですか?

私たちが知る限り、それはあなたの考えでした。この場合の利点は、あったとしても非常に限られています。この場合は不利になる可能性が高いです。

このコードでは、オブジェクト rect1(3,4) を作成した後、 rect2(5,6) を作成します。これにより、論理的に (私が思うに) 5 と 6 は、幅と高さがメモリ セクションで 3 と 4 の代わりに置き換えられます。を指しているため、3 と 4 はもう使用できませんが、使用できます。

いいえ、「論理的に(私が思うに)5と6が入れ替わる」というのは間違っています。main()それらは両方ともスコープ内にあり、ブロック の終わりまで有効です。

無効にする方法は次のとおりです。

void main()
{
    {
        CRectangle rect1(3,4), rect2(5,6);
    }

    // Note that this is no longer a valid program and will fail at compile-time
    cout << "rect1 area = " << rect1.area() << "\n";
    cout << "rect2 area = " << rect2.area();
    getch();
}

あなたの質問が、どのようにリープrect1して、rect2のヒープ割り当てが があった場所で正確に行わrect1れるかということである場合は、たとえそれが発生したとしても、この動作を本当に当てにすることはできないと思います。

于 2013-09-06T17:25:12.803 に答える