1

C ++

ポインターの値を更新するか、ポインターを変更して他の何かを指すようにする方がよいでしょうか。

ボールと座標の2つのクラスがあるとしましょう。

class ball
{
    Coordinates *ballCurrent;
    public:
        ball(int);
        ~ball();
        void setLoc(Coordinates&); // OR void setLoc(int, int);
};

class Coordinates
{
    int x, y;
    public:
        Coordinates(int, int);
        void setCoordinates(int, int);
};

ボールクラスのsetLocメソッドの場合、どのパラメーターが優れている必要がありますか?(* ballCurrent).setCoordinates(int、int)を使用してsetLocを実行するか、(ballCurrent).setLoc((new Coordinates(int、int)))を使用してsetLocを実行する方がよいでしょうか。可能であれば、それぞれの場合の理由を詳しく説明してください。

4

5 に答える 5

3

ポインターの値を更新するのと、ポインターを別のものを指すように変更するのとではどちらがよいでしょうか?

これは、文脈なしに答えられるような質問ではありません。オブジェクトが不変であることを知っておくと便利なことがよくあります。つまり、そのオブジェクトへのポインターがある限り、オブジェクトはすぐには変更されません。たとえば、関数またはメソッドが不変型へのポインターをパラメーターとして受け取る場合、関数がオブジェクトを変更することを心配することなく、オブジェクトをその関数に渡すことができます。

一方、変更可能なオブジェクトにもその場所があります。1 つには、一度にオブジェクトを作成するのではなく、いくつかのステップでオブジェクトを構築できるようにしたい場合があり、最終的なオブジェクトに到達するためだけに途中でいくつかの中間オブジェクトを作成する必要がない場合があります。

したがって、それは文脈に依存します。あなたは簡単な例を提供しているように見えますが、あなたの例でも必ずしも正しい答えがあるとは思いません。それは、あなたにとって何が重要であるか、および問題のオブジェクトがシステムの他の部分とどのように相互作用するかによって異なります。ゲームでは、いくつかのオブジェクトがボールについて知る必要がある可能性が高いため、可変オブジェクトに傾倒すると思います。ボールを動かす唯一の方法が、新しいボールを作成し、それを気にする他のすべてのオブジェクトに渡すことである場合、それは簡単に大きな問題になる可能性があります。ただし、座標オブジェクトは簡単に変更できません。ボールの位置を知る必要がある人は、ボールの位置を尋ねる必要があります。彼らはそれを取得すると、おそらく数ミリ秒ごとに場所が変更されないことを期待するでしょう. あなたがしない場合

于 2013-02-15T05:16:33.873 に答える
1

できればこのように書くかもしれません:

class ball
{
    Coordinates coordinate_;     // better name than ballCurrent?
    public:
        explicit ball(int)       // add explicit to avoid implicit converting
        : coordinate_(0,0)       // initialize corrdinate_ properly
        {
        }
        ~ball();
        void setLoc(const Coordinates& co) // add const
        {
           coordinate_ = co;
        }

        void setLoc(int x, int y)
        {
           coordinate_.setCoordinates(x,y);
        }
};

動的メモリの問題を心配する必要はありませんsetLoc。関数のオーバーロードによって 2 つの方法で発生する可能性があります。ワイルドポインターも心配もありません。

于 2013-02-15T05:11:26.437 に答える
1

新しいオブジェクトを使用する場合は、それ自体にメモリを割り当てる必要があり、初期化する必要もあります (コンストラクターの実行、プロパティの割り当てなど)。これは、既に持っている (そしてまさにその目的のために作成した) オブジェクトの値を変更するだけに比べて、かなりのオーバーヘッドです。

さらに、新しいオブジェクトを作成する場合は、以前のポインターのメモリを解放する必要がありますが、これもオーバーヘッドです...既存のオブジェクトを変更するだけです。

于 2013-02-15T05:13:16.170 に答える
0

指しているオブジェクトの値を変更するだけです。値を更新するたびにまったく新しいオブジェクトを作成するのは意味がありません。

値を変更するだけでなく、まったく新しいオブジェクトを作成する必要がある状況の 1 つは、Coordinates に const x および y 値があり、setCoordinates 関数がない場合です。しかし、座標を頻繁に更新する必要がある場合、それはほとんどの場合、設計上の決定として不適切です。

また、これではなく:

(*ballCurrent).setCoordinates(int, int);

これを使用できます:

ballCurrent->setCoordinate(int, int);

これは同じことを行いますが、書きやすく、多くの人が読みやすくなります。

于 2013-02-15T05:13:52.923 に答える
0

の場合、と の間にコンストラクターSetLoc(int,int)への依存関係を作成してballいます。さらに重要なのは、コンストラクターが表すものへの依存関係です。コンストラクターの署名が変更された場合、これらの変更を に引き継ぐ必要があります。この引数は、オブジェクト コンポーネントを初期化するために一連のパラメータを渡さないようにしたい一般的なケースで有効です。CoordinatesCoordinatesball::SetLoc

この特定のケースでは、Coordinatesは空間内の位置を具現化しており、その実装の詳細がプログラムの残りの部分に広がらないように保持するために、おそらくそれを操作するための一連のメソッドが付属している必要があります。3D 座標系に移行したい場合、理想的には、コンストラクターの呼び出しとクラスの実装だけを変更する必要があります。したがって、クラス外で必要な変更を最小限に抑える必要があります。これは、前述の問題を回避することを意味します。

オブジェクトの位置を設定する 2 つの異なるソリューションを提示しballます。実際には、これらのソリューションが表示されますか? ボールの位置がハードコーディングされている簡単なプログラムでは、それが可能であり、どちらのソリューションも機能する可能性があります。しかし、より洗練されたソフトウェアでは、ボールの位置はおそらく構成ファイルによって最初に設定され、その後の位置の更新は重要な計算の後に行われます。(int, int)この状況では、クラス内の座標に関連するすべてのロジックをカプセル化し、パラメーターの受け渡しを回避する方がはるかに保守しやすくなります。

メモリ割り当てのオーバーヘッド (たとえば、関数によって返される結果によって生成される一時) が気になる場合は、賢明な const、参照、またはポインターを使用し、適切なコピー コンストラクターを定義することで軽減する方法があります。

于 2013-02-15T05:22:27.167 に答える