1

非常にめったに使用されないいくつかのメンバー オブジェクトを含む軽量のテンプレート化されたクラスを持っているので、実際に使用するまれなケースを除いて、それらのコンストラクターとデストラクターを呼び出すことは避けたいと思います。

そのために、クラスで次のように「宣言」します。

template <class K, class V> class MyClass
{
public:
   MyClass() : wereConstructorsCalled(false) {/* empty */}
   ~MyClass() {if (wereConstructorsCalled) MyCallPlacementDestructorsFunc();}

   [...]

private:
   bool wereConstructorsCalled;
   mutable char keyBuf[sizeof(K)];
   mutable char valBuf[sizeof(V)];
};

...そして、placement new とplacement delete を使用して、実際にそうする必要がある場合にのみ、オブジェクトを設定および破棄します。

C++ FAQ を読むと、placement new を使用するときは、placement が適切に配置されていることに注意する必要があると書かれていました。そうしないと、問題が発生する可能性があります。

私の質問は、keyBuf 配列と valBuf 配列がすべての場合に適切に配置されるか、またはそれらが適切に配置されることを確認するために実行する必要がある追加の手順があるかということです。(そうであれば、プラットフォームに依存しないステップが望ましいでしょう)

4

7 に答える 7

2

適切な配置が得られる保証はありません。配列は通常、メンバータイプに対してのみ整列されることが保証されています。char配列は、の格納用に整列されますchar

唯一の例外は、charunsigned char割り当てられた配列にnewは最大の配置が与えられるため、任意の型を格納できることです。ただし、ヒープの割り当てを回避しているため、この保証は適用されません。

TR1とC++0xは、いくつかの非常に便利なタイプを追加します。

std::alignment_ofそしてstd::aligned_storage一緒にあなたにポータブルな(そして機能している)答えを与えます。

std::alignment_of<T>::valueタイプに必要な配置を提供しますT。配置とサイズstd::aligned_storage<A, S>::typeのあるPODタイプを提供します。これは、オブジェクトをタイプの変数に安全に書き込むことができることを意味します。ASstd::aligned_storage<A, S>::type

(TR1では、名前空間はstd::tr1単なるではなく、ですstd

于 2009-12-18T19:10:03.200 に答える
2

たぶん私はあなたの質問を理解していませんでしたがchar *keyBuf[..size..];、最初は NULL (未割り当て) に設定し、最初に必要なときに割り当てることはできませんか?

プレースメント new でやろうとしていることは、危険なビジネスであり、コーディング スタイルが悪いようです。

とにかく、コードの配置は実装に依存します。

于 2009-12-18T03:24:11.210 に答える
2

それらを char バッファーに配置する理由をお聞きしてもよろしいですか? K と V のポインター オブジェクトを作成し、必要なときにインスタンス化しないのはなぜですか。

于 2009-12-18T03:25:20.470 に答える
0

コード アラインメントを変更する場合は、pragma pack を使用します

#pragma pack(push,x)

// class code here

#pragma pack(pop) // to restore original pack value

x が 1 の場合、要素間にパディングはありません。

読むためのリンクはこちら

http://www.cplusplus.com/forum/general/14659/

于 2009-12-18T03:46:03.737 に答える
0

SiCrane がhttp://www.gamedev.net/community/forums/topic.asp?topic_id=455233に投稿したこの回答を見つけました。

ただし、静的割り当ての場合は、他の型との共用体でメモリ ブロックを宣言する方が無駄が少なくなります。次に、メモリ ブロックは、ユニオン内の最も制限的な型のアラインメントにアラインメントされることが保証されます。どっちにしろ相変わらず汚い。

組合がそのトリックを行うかもしれないように聞こえます!

于 2009-12-18T04:36:39.483 に答える
0

boost::optionalテンプレ見てみることをお勧めします。必要なことは実行します。使用できない場合でも、おそらくその実装を確認する必要があります。

アライメントの計算と保証にalignment_ofとを使用します。type_with_alignment

于 2009-12-18T07:26:10.847 に答える
-2

非常に長い話を非常に短くするために、これはあなたのパフォーマンスに何の役にも立たず、多くの頭痛の種を引き起こし、あなた自身のメモリマネージャーを書くことに夢中になるまでそう長くはかからないでしょう.

新しい配置は POD では問題ありませんが (ただし、何も節約できません)、コンストラクターがまったくない場合は、まったく機能しません。

また、新しい配置を使用する場合、ブール変数の値に依存することはできません。

Placement new には用途がありますが、実際にはそうではありません。

于 2009-12-18T04:57:13.830 に答える