1

私は何かが欠けているか、const-correctness がポインターで意図したとおりに機能しません (または、それが私がテストしたものであるため、おそらくスマートポインターですか?)。とにかく、これは PIMPL イディオムの変形を試してみてわかったことです。

私は次のことを宣言しています。

class A {
public:
  A(...);
  ...
  bool update_stuff(...) const;
  ...
protected:
  bool update_stuff_impl(...) const;
  ...
private:
  struct pimpl;
  pimpl* m_pimpl;
};

そして、実装のために、私は次のようなものを持っています:

struct A::pimpl {
  pimpl(...): some_data(new some_type());
  ...
  some_method1(...); // Modifies content of some_data
  some_method2(...); // Modifies content of some_data 
  ...

  boost::shared_ptr<some_type> some_data;
};

A::A(...): m_pimpl(new pimpl(...)) {
  ...
}

bool A::update_stuff(...) const {
   if( !update_stuff_impl(...) ) {
      return false;
   }
   return true;
}

bool A::update_stuff_impl(...) const {
   //-Change content of pimpl::some_data here
   m_pimpl->some_method1(...);
   m_pimpl->some_method2(...);
   return true;
}

私が理解に苦しんでいるconstのは、関数A::update_stuff(...)に修飾子を使用する方法とA::update_stuff_impl(...)、実際に変更している場合ですA::pimpl::some_data??! それとも、これは予想される動作ですか、それとも単なる悪い使用法ですか? 後者の場合は、どのように修正できるかを特定していただければ幸いです。

お時間と関心をお寄せいただきありがとうございます。

4

2 に答える 2

2

C++ は変数の constness を保護しpimpl* m_pimplます。ポインタの値を変更することはできません。ただし、このポインターが指しているオブジェクトに対して何でも行うことができます。通常、それを保護する方法はありません。

たとえば、クラス メンバー変数について考えてみますint a; int* b;。クラスメンバー関数では、次のことができます。

int a_copy = a;
a_copy = 42;
int* b_copy = b;
*b_copy = 42;

a_copyとはローカルb_copy変数です。これらは、現在のオブジェクトの constness で保護されていません。そのため、このコードは const メソッドを使用して実行できます。違いは、aここでは変数の値が変更されておらず、*b値が変更されていることです。ポインターは簡単にコピーできるため、あるポインターが const オブジェクトのメンバー値にあるポインターと等しいかどうかをコンパイラーが知る方法はありません。

于 2013-06-09T07:30:56.980 に答える