1

重複の可能性:
C++-クラスでポインタメンバーを使用する必要があるのはいつですか

私は何年もc++で作業してきましたが、まだ答えていない質問があります。私はc ++クラスを定義していますが、これについていくつか疑問があります。

質問1:ポインターを使用して投資を保存する必要がありますか?

Investment* investment;
// or
Investment investment;

質問2:なぜですか?

質問3:使用する場合Investment investment;、この方法で参照を返す必要がありInvestment & getInvestment();ますか?

私は自分のコードが両方の方法で機能することを知っていますが、これを行うための効率的な方法を知りたいです。

コードは次のとおりです。

class Urgency
{
private:
    Investment* investment;
public:
    Urgency(Investment* investment);
    ~Urgency(void);

    Investment* getInvestment();
};
4

5 に答える 5

3

私は通常、オブジェクトが大きい場合はポインターを使用し、小さい場合はスタックオブジェクトを使用することを好みます。ポインターは、遅延初期化や前方宣言などのいくつかのことを可能にしますが、スタックオブジェクトは、独自のコピーコンストラクターを作成する必要があり、デストラクタでオブジェクトを明示的に破棄することを心配する必要がある可能性のあるフードを減らします。(ただし、共有ポインター型オブジェクトを使用してこれを行うこともできます)また、スタックオブジェクトは通常、アクセスが高速ですが、ほとんどのシナリオでは、これがほとんどの場合の違いとしてどちらかを選択する理由にはなりません。アプリケーションはごくわずかです。

コードを参照すると、通常、const Investment &Investmentオブジェクトを直接変更できないようにするためにを返します。上記のように、rawポインタを使用する場合は、オブジェクトのメモリを適切に管理するコピーコンストラクタとデストラクタを作成する必要があります。ポインタオブジェクトを使用すると、通常はconst Investment *もう一度戻って、外部の呼び出し元がオブジェクトを直接変更する機能を削除します。

constの正しいInvestmentオブジェクトを返すときに、Investmentクラスで関数がどのように宣言されているかに注意してください。を持っているだけではInvestment::getNumShares()、const参照またはconstポインターを使用して関数にアクセスすることはできません。この問題を修正するには、オブジェクトを変更しないすべてのメンバー関数をconstにマークします。Investment::getNumShares() const

于 2012-11-13T04:31:36.530 に答える
1
  1. どうしても必要な場合を除いて、ポインタは使用しないでください
  2. 注意深く使用しないとエラーが発生しやすいためです
  3. さらに良いことに、誰もがあなたの変更を行うことを許可する予定がない場合は戻っconst &てくださいInvestment
于 2012-11-13T04:31:11.243 に答える
1

質問1/2:ポインターを使用して投資を保存する必要がありますか?/ どうして?

Investment* investment;
// or
Investment investment;

それぞれに長所と短所があります。

ポインタを使用しない:

  • Investmentオブジェクトの作成と削除について心配する手間が省けます。ただし、必要に応じて、初期化リストでInvestmentコンストラクターを明示的に選択できます。
  • Investmentオブジェクトがホストオブジェクト内に割り当てられていることを意味します。これにより、ヒープの割り当てと割り当て解除を節約できます。これにより、メモリ効率が向上し、パフォーマンスが向上する可能性があります。

ポインターの使用:

  • 遅延初期化を使用できます。包含オブジェクトが実際に必要になるまでInvestmentオブジェクトの作成を延期し、不要になったときに再度削除することができます。このライフタイムの手動制御は、メモリ使用量を微調整するために使用できます。実際の投資を指していないときにポインタにNULL/0を格納することは、これを追跡するのに役立つ一般的な方法です。
  • オブジェクトの外部のコードにInvestmentオブジェクトの所有権を与えることができることを意味します...彼らはそれを使い続け、必要に応じて削除することができます。
  • つまり、コピーコンストラクターを慎重に作成し、コンストラクターで例外を慎重に処理する必要があります。スマートポインタはこれらのことを助けることができるかもしれません。
  • Investmentから派生したクラスのインスタンスを割り当て、同じポインターを介してそれを使用できることを意味します。これにより、実行時のニーズに適したカスタム実装を選択したり、ニーズの変化に応じて実装を変更したりすることができます。この柔軟性は、オブジェクト指向プログラミングとランタイムポリモーフィズムの基礎です。
  • 包含オブジェクトのヘッダーは、(同じファイルによって、#includeまたは同じファイル内で)Investmentクラスの前方宣言のみを確認する必要があることを意味します。これは、包含オブジェクトのみを使用するコードの再コンパイルを強制することなく、Investmentオブジェクトに変更を加えることができることを意味します(変更されたInvestment実装を含むオブジェクトの再リンクのみが必要になります)。概念は、実装へのポインタまたはpImplイディオムと同じですが、Investmentは必ずしも包含クラスの実装の専用部分ではなく、プログラムの他の場所で直接独立して使用できます。

質問3:投資投資を使用する場合。この方法で参照を返す必要がありますInvestment&getInvestment();?

それはプログラムに大きく依存します。データメンバーを直接公開することを避け、代わりに、投資で何らかの作業を行う包含オブジェクトでより高いレベルの論理関数を提供することが最善の場合があります。これにより、投資オブジェクトの周囲に余分な不変条件を維持できます。つまり、制御、調整、およびいつどのように使用されるかを監視します。それ以外の場合は、それを公開する方が実用的かもしれません。

参照を返すことは、実際に返すInvestmentオブジェクトがあることが確実な場合にのみ適切です。ポインターバージョンでは、実装にnewInvestmentオブジェクトがまだない場合は、実装で作成する必要があります。または、ポインタを返すということは、クライアントコードにNULL / 0を返して、Investmentオブジェクトがまだないことを示すことができることを意味しますが、クラスとクライアントコードが、誰が継続的な所有権を持つかを理解していることを確認する必要があります(つまり、投資オブジェクトに対する権利/義務delete)、およびどちらの側も、相手側がそれを行った後、投資を使用しようとはしませんdelete

于 2012-11-13T04:46:23.177 に答える
0
  • ポインタを使用することで、メモリを割り当てるタイミングと削除するタイミングを選択できますが、通常の宣言には自動ストレージがあります。質問に答えるために、それはあなたが書いているプログラムのタイプと個人的な好みに本当に依存します。

    class Foo
    {
        Foo* Obj; //choose when to allocate this object, dynamically allocated
        Foo Obj2; //automatic, runs through the life of the object.
    }
    
  • 可能ですが、アドレスを割り当てるための代替ソリューションは、オブジェクトの参照を設定するパラメーターを受け取るvoid関数を使用することです。

    void GetVar(int *Address_Holder)
        {
            //assign address
        }
    
于 2012-11-13T04:30:11.873 に答える
0

オブジェクトにメモリを割り当てるタイミングと削除するタイミングを制御する場合は、ポインタを使用します。巨大なサイズのオブジェクトがある場合は、関数へのポインターの受け渡しがオブジェクト自体の受け渡しよりも高速であるため、ポインターを使用します(または、uは参照で渡すことができます)。それ以外の場合は、ポインタを使用するとエラーが発生しやすいため、ポインタではなくオブジェクトを使用することをお勧めします。

于 2012-11-13T04:38:48.917 に答える