1

事実上 Python のオブジェクトの類似物であるオブジェクトを作成しようとしていlistます。私のコードには、次のクラスがあります: object_type, type_type, none_type, bool_type, int_type, float_type,bytes_typeobject_type抽象クラスです。

抽象クラスには、、、、、、、、などの仮想関数がいくつtype_type __type__(void)かあります。bytes_type __name__(void)bytes_type __repr__(void)bool_type __bool__(void)int_type __int__(void)float_type __float__(void)bytes_type __bytes__(void)

type_typeクラスには次のコンストラクタがありますtype_type(object_type*)。構築中、ソース オブジェクトへのポインタが格納されobject_type* type_type::__cdata__、ユーザーが関数を使用して 2 つの型を比較したい場合に使用されますtype_type::__eq__(const type_type&)(この関数はtypeid、ご想像のとおり使用します)。

list_typeに基づく任意のオブジェクトを格納できるオブジェクトを作成する必要がありますobject_type__get__(const int_type&)要素を取得する__set__(const int_type&, object_type*)関数と要素を設定する関数が必要です。すべてのオブジェクトは の中に格納されstd::vector<object_type*> __cdata__ます。

list_type::__get__(const int_type&)正しいオブジェクトを強制的に返すにはどうすればよいですか? list_type次の3 つの要素を含むがあるとします[bytes_type object0, int_type object1, float_type object3]。を使用list_type::__get__(0)すると、 が返されbytes_type object0ます。おそらく関数type_type object_type::__type__()は便利です。

ユーザーがobject_type実行中に新しいベース型を作成することは困難です (私が説明したことはすべて、新しいおもちゃ言語を作成するために使用されます)。ただし、すべての型は仮想関数に基づいてobject_typeおり、その仮想関数を持っています。

あなたはなにか考えはありますか?アドバイスをいただければ幸いです。

PS git リポジトリ: https://github.com/ghostmansd/quirinus

4

2 に答える 2

1
All objects are stored inside std::vector<object_type*> __cdata__.

How can I force list_type::__get__(const int_type&) to return correct object?

にはすでに正しいオブジェクトがありますstd::vector<object_type*>。タイプはobject_type*です。object_type*またはのいずれかを返す必要がありますobject_type&。これらは可能な限り最高の返品タイプです。C ++型システムは、関数の戻り型がその入力に依存するほど洗練されていません。

ただし、生のポインターではなくスマートポインターを使用することを検討する必要がありますが、原則は同じです。

サイドノート。参照またはポインタ(スマートまたは生)を使用して何ができますobject_typeか?2つのこと:それを他のポインターまたは参照にキャストするか、それを介して仮想関数を呼び出すことができます。キャストは、ターゲットタイプを知っているか推測できる場合にのみ役立ちます。また、想像できる操作のセットは無限にあるため、仮想関数を介して考えられるすべての操作を実装することは実用的ではありません。これはおそらく、このデザインがあなたがやりたいことに最適なものではないことを意味します。

ああ、C++では二重アンダースコアを使用しないでください。

于 2013-01-06T16:02:15.553 に答える
1

メソッドで使用するメソッド規則は、非常に python に似ています。@BenjaminLindley が言ったように、これは無効です。C++ では、2 つのアンダースコアで始まる名前はコンパイラに予約されているためです (Python では、これらは のような特別なメソッド用に予約されています__eq__が、C++ では == を同様の効果のためにオーバーロードできます)。

注: 以下は、コンパイル時に既知の型に対して機能します。

C++ は静的に型付けされるため、複数の型を返すことはできません。object_type& を返す必要があります。これは、元の型にキャストすることができます:

リストは object_type への (スマート) ポインターを格納でき、get メソッド (またはオーバーロードされた[]演算子) は object_type への参照を返します。

// data is underlying container of pointers, getInt() returns int value from int_type
object_type& get(const int_type& i) { return *(data[i.getInt()]); }

ここでは、スライスを回避し、リストに格納されている値にアクセスするために参照が使用されます。

ユーザーは、オブジェクトの元の型を取得するためにキャストする必要があります。

try
{
    bytes_type& object0 = dynamic_cast<bytes_type&>(your_list.get(0))
    // operate on object0
}
catch(std::bad_cast& e)
{
     // type was incorrect
     std::cout << "Invalid type";
}

boost::any はこのアイデアに似ているため、彼らがどのように実装したかを見ることができます。

于 2013-01-06T13:50:12.430 に答える