3

C++ でポインターを学習していますが、問題が発生しています。Fooヘッダー ファイルでいくつかのデータを宣言するクラスがあります。

private:
const Bar *obj;

Barクラスはどこですか。

次に、C++ 実装で、完全に異なるオブジェクト*objを指すように置き換えたいと思います。は定数なので、どのように何を指すか、または何をメモリに置いているかを変更するにはどうすればよいですか? のデストラクタでも、どのように割り当てを解除しますか?Bar*obj*obj*objFoo*obj

4

4 に答える 4

4

あなたのクラス定義を考える

class A {
private:
  const Bar *obj;
};

obj定数Barオブジェクトへのポインタです。そのポインターが指すものを変更することはできますが、指しているオブジェクトの内容を変更することはできません。

したがって、新しいオブジェクトがあり、それを指すBarように変更したい場合は、新しい値を割り当てるだけです。obj

/* New object: */
Bar *new_bar = new Bar;
/* Change the pointer: */
obj = new_bar;

ただし、2 つの問題があります。

  1. 新しいBarオブジェクトがクラスの外部objで作成された場合、後者はプライベートであるため、直接割り当てることはできません。したがって、セッター関数が必要です。

    class A {
    private:
      const Bar *obj;
    public:
      void set_obj(const Bar *new_obj) { obj = new_obj; }
    };
    
  2. 最終的にBarオブジェクトを所有するのは誰か、つまりオブジェクトが必要とするヒープ領域を解放する責任を負うのは誰かを決定する必要があります。呼び出し元に責任がある場合は、上記のようにコーディングできます。つまり、class A新しいBarオブジェクトを作成したり削除したりしません。Barクラス外で作成および削除されたオブジェクトへのポインタを維持するだけです。

    ただし、class A上記が実際にBarオブジェクトによって使用されるメモリ領域の原因である場合は、デストラクタで使用して領域を解放する必要があり、新しいオブジェクトが割り当てられdelete objたときにも領域を解放する必要があります。Barつまり、set_obj上記の関数を次のように変更する必要があります。

    void set_obj(const Bar *new_obj) { delete obj; obj = new_obj; }
    

    そうしないと、メモリリークが発生します。コピー コンストラクター (削除しない限り) と代入演算子でも同様の措置を講じる必要があります。オブジェクトのコピーが作成されるたびに、両方の関数が使用されます。ただし、代わりに新しいスペースを割り当ててオブジェクトをコピーします (つまり、ディープ コピーを実行する必要があります)。class A

    A(const A& a):obj(new Bar(*a.obj)) {}
    A& operator=(const A& a) { delete obj; obj = new Bar(*a.obj); return *this; }
    

    そうは言っても、クラスがメモリ空間を担当している場合は、生のポインターの代わりにスマート ポインター クラスを使用することをお勧めします主な理由は次のとおりです。(i) 上記は非常に複雑で、間違いを犯しやすい。(ii) 上記はまだあまり良くありません – のコンストラクターなどで例外がスローされると、メモリ リークやさらに悪い問題が発生する可能性がありますBar。C++11 は と呼ばれるスマート ポインター クラスを提供しstd::unique_ptrます。これは目的に適していると思われます。

    class A {
    private:
      std::unique_ptr<const Bar> obj;
    public:
      ~A() {}
      void set_obj(std::unique_ptr<const Bar> new_obj) { obj = new_obj; }
    };
    

    Barこれにより、スマート ポインターは、破棄時と新しいオブジェクトがポインターに割り当てられるときの両方で、自動的に解放する必要があるすべてのメモリ領域を処理します。

于 2012-10-24T01:15:14.877 に答える
1

そのポインターを使用して、指している値を変更することはできません。そのため、それは const ですが、指している対象を変更できるはずです。

于 2012-10-24T00:53:27.140 に答える
1

C++ では「const Bar *obj;」読み取り専用の Bar オブジェクトへのポインターがあることを意味します。つまり、任意の読み取り専用 Bar オブジェクトを指すことができます。

非定数変数を指すこともできるため、そのポインターを使用して変数を変更しないことを約束します。

ポインタが必要な場合、それは他のものを指すようにすることができないという意味で一定であり、次のように記述する必要があります。

Bar * const obj = some_object;

これはコンパイルされ、正常に動作します:

const int p = 1, q = 2;
int r = 3;
const int* i = &p;
i = &q; // point it to a different const variable.
i = &r; // point it to a different non const variable.
于 2012-10-24T01:00:14.170 に答える
0

書かれているように、これは const Bar オブジェクトへのポインターであり、定数ポインターではないと思います。

于 2012-10-24T00:56:39.267 に答える