おはようございます!C++:オブジェクトのプロパティエミュレーション:思考
プロパティはC++では実装されていません。私たちが書くことはできません。
myObject.property = value; // try to set field f_ to value
はproperty
は私的なデータメンバーです。パブリックデータメンバーはOOPカプセル化ルールに違反します。
代わりに、私たちは、ゲッター/セッターのコードを記述する必要があります。
myObject.setField(value); // try to set field f_ to value
この投稿は、C++約プロパティエミュレーションです。 プロパティ呼び出しはパブリックデータメンバー呼び出しのように見えますが、カスタムUDFコードは実際のプライベートデータメンバー値を設定または取得するために使用されます。
は、単純なインターフェイス使用(関数呼び出し構文のようなパブリックデータメンバーのような)を可能にしますが、基礎となるgetter/setterは複雑です(データ割り当て/読み取りのみを行う)です。
次のコード(私の同僚が書いた)単純なプロパティの実装を提示:
#include <iostream>
template<class C, class M>
inline C* get_parent_this(typename M C::*member_ptr, M*const member_this)
{
//interpret 0 as address of parent object C and find address of its member
char* base = reinterpret_cast<char*>(nullptr);
char* member = reinterpret_cast<char*>(&(reinterpret_cast<typename C*>(base)->*member_ptr));
//modify member_this with offset = (member - base)
return reinterpret_cast<typename C*>(reinterpret_cast<char*>(member_this) - (member - base));
}
class Owner
{
int x,pr_y;
int get_y() {return pr_y;}
void set_y(int v) {pr_y = v;}
public:
struct
{
operator int() { return get_parent_this(&Owner::y, this)->get_y(); }
void operator =(int v) { get_parent_this(&Owner::y, this)->set_y(v); }
} y;
};
int main()
{
Owner ow;
ow.y = 5;
std::cout << ow.y;
if(get_parent_this(&Owner::y, &ow.y) == &ow) std::cout << "OK\n";
if((char *)&ow.y != (char *)&ow) std::cout << "OK\n";
return 0;
}
シンプルなゲッター/セッターのペアは、その上の例ではありますが、追加の仕事をしていない(例えば整合性チェックまたは境界チェック)ですが、このコードは境界チェック、完全性チェックなどの複雑な処理になる可能性があります。 これはテスト例です。
get_parent_this
ヘルパーテンプレートの「奇妙な」コードは心配しないでください。最も恐ろしいことは、オフセット計算です。 nullptr(NULL、0x0)アドレスはスタブとして使用されます。私たちはこのアドレスに書いたり読んだりしません。サブオブジェクトアドレスに基づいて、オーダーオブジェクトのオフセット計算をにのみ使用します。 0x0の代わりに任意のアドレスを使用できます。だから、これは意味をなさない。
プロパティの使用:
- 誰かが使用している場合は、パブリックデータメンバーのプロパティは、場合に役立つかもしれない: 1.1。何かが間違っているとパブリックデータメンバーのコールを追跡する。 1.2。パブリックデータメンバーの使用に基づいた痛みを伴わないレガシーコードをアップグレードする。
- あなたは、C++でのプロパティのエミュレーションについてどう思いますか?活発なアイデアですか?このアイデアには欠点がありますか(ショー、どうぞ)?
- サブオブジェクトアドレスからオーナーオブジェクトのアドレス計算についてどう思いますか?あなたが知っている技術と潜在的な落とし穴は何ですか?
あなたのご意見をお聞かせください。
ありがとうございました!
私は本当に理解していません。パブリックデータメンバーの問題は何ですか? – pmr
幸運にも、慣用的なC++では、あなたが考えるかもしれないように、「プロパティ」もゲッターもセッターも全く必要でないことがよくあります。 –
2度目の読書で、これは私がしばらく読んだ中で最も恐ろしいコードでなければなりません。 「悪い」ではなく、深い実在の不安を引き起こすという意味で、ただ「恐ろしい」ことを心に留めてください。 –