6

私はもともと C で書かれた大きなアプリケーションを継承しました (ただし、その間に多くの C++ も追加されました)。歴史的な理由により、アプリケーションには多数の void ポインターが含まれています。窒息し始める前に、なぜこれが行われたのかを説明させてください.

アプリケーションにはさまざまなデータ構造が含まれていますが、それらは「汎用」コンテナに格納されています。最近では、テンプレート化された STL コンテナーを使用するか、すべてのデータ構造に共通の基本クラスを与えて、コンテナーが基本クラスへのポインターを格納できるようにしますが、[良い?] 古い C 時代には、唯一の解決策はstruct-pointer を void-pointer にキャストします。

さらに、これらの void ポインターで機能するコードが多数あり、C でポリモーフィズムをエミュレートするために非常に奇妙な C 構造を使用します。

私は現在、アプリケーションを作り直しており、void ポインターを取り除こうとしています。すべてのデータ構造に共通の基本クラスを追加するのはそれほど難しくありません (数日かかります) が、問題は、コードが以下に示すような構造でいっぱいであることです。

これは、データの保存方法の例です。

void storeData (int datatype, void *data);    // function prototype
...
Customer *myCustomer = ...;
storeData (TYPE_CUSTOMER, myCustomer);

これは、データが再度フェッチされる方法の例です。

Customer *myCustomer = (Customer *) fetchData (TYPE_CUSTOMER, key);

実際には、すべての void ポインターをいくつかのスマート ポインター (参照カウント) に置き換えたいのですが、自動化するためのトリックが見つかりません (または少なくとも) void- との間のすべてのキャストを取り除くのに役立ちます。ポインター。

これらの変換を見つけたり、置き換えたり、何らかの方法で操作したりするためのヒントはありますか?

4

3 に答える 3

7

実際には、すべての void ポインターをいくつかのスマート ポインター (参照カウント) に置き換えたいのですが、自動化するためのトリックが見つかりません (または少なくとも) void- との間のすべてのキャストを取り除くのに役立ちます。ポインター。

このような自動化されたリファクタリングには、多くのリスクが伴います。

それ以外の場合は、そのような void* 関数をテンプレート関数にすることで、いたずらをするのが好きなことがあります。それか:

void storeData (int datatype, void *data);

になります:

template <class T>
void storeData (int datatype, T *data);

最初に、元の (名前が変更された) 関数をラップして型を変換するだけで、テンプレートを実装します。これにより、コードをコンパイルするだけで、潜在的な問題を確認できる場合があります。

于 2010-06-11T22:49:52.747 に答える
0

どうやら、void-pointers のすべての使用を変換または検索するための自動化された方法/トリックはありません。PC-Lint と組み合わせて、すべての void ポインターを見つけるために手作業を使用する必要があります。

ケースを閉じました。

于 2010-06-17T12:48:13.310 に答える
0

おそらく、共有ポインタを使用するためにキャストを取り除く必要はありません。

storeData(TYPE_CUSTOMER, myCustomer1->get());

shared_ptr<Customer> myCustomer2(reinterpret_cast<Customer*>fetchData(TYPE_CUSTOMER, "???");

もちろん、これはストア/フェッチへの呼び出し間で同じポインターを共有することを想定していないことを前提としています。つまり、myCustomer1 と myCustomer2 は同じポインターを共有しません。

于 2010-06-11T21:06:53.150 に答える